Creating a bubble displacement effect

edited May 2017 in GLSL / Shaders

Just implemented a voronoi frag shader, really happy with the results, and now I'm working on using it to displace a video. I'd like to displace it with the voronoi cell point as the center, to make a kind of voronoi bubble effect, but I can't seem to get the math just right to make the distortion radiate from the point in a realistic way. Does anyone have some tips?

Here is what I have so far:

uniform sampler2DRect tex0;

varying vec2 texcoord0;

uniform float strength;

uniform float time;
uniform float scale;
uniform float speed;
uniform vec2 dim;

uniform float rand_seed;

float rand(vec2 co){
    return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}

void main()
{
    vec2 st = vec2(gl_FragCoord.xy/dim.xy);
    st.x *= dim.x/dim.y;
    vec2 displacement = vec2(1.);

    st *= scale;

    vec2 i_st = floor(st);
    vec2 f_st = fract(st);

    float m_dist = 1.;
    vec2 m_point;

    for(int y = -1; y <= 1; y++){
        for(int x = -1; x <= 1; x++){
            vec2 neighbor = vec2(float(x),float(y));
            vec2 point = vec2(rand((i_st + neighbor)*rand_seed));

            point = 0.5 + 0.5*sin((time/speed) + 6.2831*point);

            vec2 diff = neighbor + point - f_st;

            float dist = length(diff);

            if(dist < m_dist){
                m_dist = dist;
                m_point = point;
            }
        }
    }

    //displacement vector
    //TODO: How can I conform this to the voronoi shape? 
    //displacement = vec2(m_dist - m_point) - m_dist; //this is great, and a possible alt to the working voronoi
    displacement = m_dist * vec2(m_point - vec2(gl_FragCoord.xy/dim.xy)); 
    //can the vec2 come back negative?

    //isolines
    //color -= step(.7,abs(sin(100.0*m_dist)))*.3;

    //point dot
    //displacement -= 1.-step(.05, m_dist);


    vec2 uv0 = texcoord0 / dim;

    uv0.x += uv0.x * (displacement.x/strength);
    uv0.y += uv0.y * (displacement.y/strength);

    vec3 color = texture2DRect(tex0, uv0*dim).xyz;

    gl_FragColor = vec4(color,1.0); 
}

Answers

  • edited May 2017

    @AceSlowman

    WHERE IS THE PDE ?

    //processing.org/reference/PShader.html
    
    
    PShader conway;
    
    void setup() {
      size(640, 360, P2D);
      // Shaders files must be in the "data" folder to load correctly
      conway = loadShader("https://"+"pastebin.com/raw/w0cjNYZN"); 
    
      //set uniforms that don't need to be updated
      conway.set("resolution",float(width),float(height));
    
      //compile shader
      shader(conway);
    
    }
    
    void draw() {
    
      //time
      conway.set("time", frameCount*.01f); 
    
      //mouse:  processing.org/reference/map_.html
      conway.set("mouse",map(mouseX, 0, width, 0, 1),map(mouseY, 0, height, 1, 0));
    
      //paint the shader to a rectangle
      rect(0, 0, width, height);
    }
    

    @AceSlowman Center is not center in Processing
    you should try things.

    P2D and P3D - filter( ) vs shader( ) etc.

    Find what fits your task.

    Start simpel with a circel then implement a voronoi

    Here e.g works great with rect(RADIUS)

    PShader shdr;
    
    void setup() {
      size(640, 340, P2D);
    
      noStroke();
      rectMode(RADIUS);
    
      shdr=new PShader(this, 
        new String[]{"#version 150 \n"
        + "in vec2 position;"
        + "void main() {"
        + "gl_Position = vec4(position.xy,0.,1.);"
       + "}"  
        }, new String[]{"#version 150 \n"
          + "out vec4 fragColor;"
          + "uniform vec3 iResolution;"
          + "void main() {"
          + "vec2 uvv = (gl_FragCoord.xy*2.-iResolution.xy)/iResolution.z;"
          + "float cir=.2/length(uvv);"
          + "fragColor = vec4(vec3(cir),1.);"
         +"}"
          }){
          PShader run(){
          this.set("iResolution",new PVector(width,height,Math.min(width,height)));
          return this;
          }
        }.run();
        shader(shdr);
    
    }
    
    void draw() {
      background(0);
      rect(0,0,width,height);
    }
    
Sign In or Register to comment.