How to make a wave warp effect in a shader?

I want to make the wave warp effect as follows:

wave1

But I can only create a normal sine wave.

Here is my fragment shader:

precision mediump float; varying vec2 v_texCoord; uniform sampler2D s_baseMap; vec2 SineWave( vec2 p ){ float pi = 3.14159; float A = 0.15; float w = 10.0 * pi; float t = 30.0*pi/180.0; float y = sin( w*px + t) * A; return vec2(px, p.y+y); } void main(){ vec2 p = v_texCoord; vec2 uv = SineWave( p ); vec4 tcolor = texture2D(s_baseMap, uv); gl_FragColor = tcolor; } 

and the result:

wave2

So, the question is how to deform a wave in a certain direction?

thanks.

here is the texture of origin: original texture


update: I distort the x axis when calculating y, but the result seems wrong.

 float x = px + py*tan( -0.5); float y = sin( w*x + t) * A; return vec2(px, p.y+y); 

change x axis

+6
source share
1 answer

OK I tried to restore your effect, so I used it as a texture:

texture

I took your image and resized it to 512x512 so that force 2 fills the border with black. Since you are not using Vertex shader, I created my own. GL displays one quad <-1,+1> without texture coordinates or matrices, only glVertex2f() with a single 2D texture, bound to unity 0 . I rewrite the fragment a bit to match the output. I also added the tx,ty form to easily animate the effect with the mouse position <0,1> Here is the first vertex of the shaders:

 // Vertex varying vec2 v_texCoord; void main() { v_texCoord=gl_Vertex.xy; gl_Position=gl_Vertex; } 

And then the snippet:

 // Fragment varying vec2 v_texCoord; // holds the Vertex position <-1,+1> !!! uniform sampler2D s_baseMap; // used texture unit uniform float tx,ty; // x,y waves phase vec2 SineWave( vec2 p ) { // convert Vertex position <-1,+1> to texture coordinate <0,1> and some shrinking so the effect dont overlap screen px=( 0.55*px)+0.5; py=(-0.55*py)+0.5; // wave distortion float x = sin( 25.0*py + 30.0*px + 6.28*tx) * 0.05; float y = sin( 25.0*py + 30.0*px + 6.28*ty) * 0.05; return vec2(p.x+x, p.y+y); } void main() { gl_FragColor = texture2D(s_baseMap,SineWave(v_texCoord)); } 

This is output for tx=0.3477,ty=0.7812 , which visually more or less matches your example:

output

As you can see, I added several terms to the sin waves to get distorted distortion.

If you have v_texCoord already in the range <0,1> , then ignore

  px=( 0.55*px)+0.5; py=(-0.55*py)+0.5; 

or rewrite it (so that the shrinkage and coefficients remain the same as they should)

  px=(1.1*px)-0.05; py=(1.1*py)-0.05; 

If you use a different texture (not mine), you need to rescale all the coefficients.

[edit1] odds meaning

I first started with your:

 float x = sin( 10.0*py) * 0.15; float y = sin( 10.0*px) * 0.15; 

0.15 - the amplitude of the wave, which seems too large, so I lower it to 0.05 . Then 10.0 is the frequency, the greater the number, the more waves along the axis. From a pure trial error, I determine that they should be 30.0 for the y axis and 25.0 for the x axis, so the number of waves matches your desired result.

 float x = sin( 25.0*py) * 0.05; float y = sin( 30.0*px) * 0.05; 

After that, I noticed that the waves should be slightly skewed, so I add a dependency on the other axis, too, after some tweaking, which detected this equation:

 float x = sin( 25.0*py + 30.0*px) * 0.05; float y = sin( 25.0*py + 30.0*px) * 0.05; 

where both coefficients are the same between the axes (strange, but working, I expected that I would need to have different coefficients between the axes). After that, you just need to find the correct phase for each axis, so I add a phase shift controlled by the mouse position (tx,ty) <0.0,1.0> , so I got the final version:

 float x = sin( 25.0*py + 30.0*px + 6.28*tx) * 0.05; float y = sin( 25.0*py + 30.0*px + 6.28*ty) * 0.05; 

Then I play with the mouse (print its position) until I get close enough to match your desired result, which was when tx=0.3477,ty=0.7812 so that you can hardcode

 float x = sin( 25.0*py + 30.0*px + 6.28*0.3477) * 0.05; float y = sin( 25.0*py + 30.0*px + 6.28*0.7812) * 0.05; 
+8
source

All Articles