问题描述
我想像这样产生波浪翘曲效果:
I want to make a wave warp effect like this:
但是我只能创建普通的正弦波.
But I can only create the normal sine wave.
这是我的片段着色器:
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*p.x + t) * A;
return vec2(p.x, p.y+y);
}
void main(){
vec2 p = v_texCoord;
vec2 uv = SineWave( p );
vec4 tcolor = texture2D(s_baseMap, uv);
gl_FragColor = tcolor;
}
结果是:
所以问题是如何在特定方向上弯曲波浪?
So the question is how to warp the wave on a specific direction?
谢谢.
以下是原点纹理:
更新:在计算y时我扭曲了x轴,但结果似乎不正确.
update:I distort x axis when compute y, but the result seems not right.
float x = p.x + p.y*tan( -0.5);
float y = sin( w*x + t) * A;
return vec2(p.x, p.y+y);
推荐答案
好,我尝试重新创建效果,所以我将其用作纹理:
OK I tried to recreate your effect so I used this as texture:
我拍摄了您的图像并将其大小调整为,所以它是2的幂,用黑色填充边框.由于您不共享Vertex着色器,因此我创建了自己的着色器. GL 正在渲染没有纹理坐标的单一四边形<-1,+1>
或仅将 2D 纹理绑定到单元0
的矩阵glVertex2f()
.我稍微重写您的片段以匹配输出.另外,我添加了tx,ty
制服,以轻松地用鼠标位置为效果设置动画效果.<0,1>
这是着色器的第一个顶点:
I took your image and resize it to 512x512
so it is power of 2 fill the border with black. As you do not share Vertex shader I created my own. The GL is rendering single quad <-1,+1>
without texture coordinates or matrices only glVertex2f()
with single 2D texture binded to unit 0
. I slightly rewrite your fragment to match the output. Also I added tx,ty
uniforms to easily animate the effect with mouse position <0,1>
Here are the shaders first vertex:
// Vertex
varying vec2 v_texCoord;
void main()
{
v_texCoord=gl_Vertex.xy;
gl_Position=gl_Vertex;
}
然后片段:
// 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
p.x=( 0.55*p.x)+0.5;
p.y=(-0.55*p.y)+0.5;
// wave distortion
float x = sin( 25.0*p.y + 30.0*p.x + 6.28*tx) * 0.05;
float y = sin( 25.0*p.y + 30.0*p.x + 6.28*ty) * 0.05;
return vec2(p.x+x, p.y+y);
}
void main()
{
gl_FragColor = texture2D(s_baseMap,SineWave(v_texCoord));
}
这是tx=0.3477,ty=0.7812
的输出,它在视觉上或多或少与您的示例匹配:
This is output for tx=0.3477,ty=0.7812
which visually more or less matches your example:
如您所见,我在正弦波中添加了一些术语,因此它也出现了歪斜失真.
As you can see I added few terms into the sin waves so it got also skew distortion.
如果v_texCoord
已经在<0,1>
范围内,则忽略
If you have the v_texCoord
already in range <0,1>
then ignore the
p.x=( 0.55*p.x)+0.5;
p.y=(-0.55*p.y)+0.5;
或将其重写为(这样,收缩率和系数就应保持不变)
or rewrite it to (so the shrink and coefficients stay as should)
p.x=(1.1*p.x)-0.05;
p.y=(1.1*p.y)-0.05;
如果使用其他纹理(不是我的纹理),则需要重新缩放所有系数.
If you use different texture (not mine) then you need to rescale all the coefficients.
[edit1]系数含义
首先我从你的开始:
float x = sin( 10.0*p.y) * 0.15;
float y = sin( 10.0*p.x) * 0.15;
0.15
是波幅,似乎太大了,因此我将其降低到0.05
.那么10.0
是频率,数字越大,沿轴的波将越多.通过纯粹的试错法,我确定对于y轴,它们应该是30.0
,对于x轴,它们应该是25.0
,以便波数与您所需的输出相匹配.
The 0.15
is wave amplitude which seems to be too big so I lower it to 0.05
. Then 10.0
is frequency the bigger the number the more waves along axis will be. By pure trial&error I determine they should be 30.0
for y axis and 25.0
for x axis so the number of waves matches your desired output.
float x = sin( 25.0*p.y) * 0.05;
float y = sin( 30.0*p.x) * 0.05;
此后,我发现波浪应该稍微偏斜,因此在进行一些调整后,我也增加了对另一轴的依赖性:
After this I spotted that the waves should be a bit skewed so I add dependency on the other axis too after some tweaking found out this equation:
float x = sin( 25.0*p.y + 30.0*p.x) * 0.05;
float y = sin( 25.0*p.y + 30.0*p.x) * 0.05;
轴之间的两个系数都相同(这很奇怪,但是我期望我在轴之间需要具有不同的系数).之后,只需找到每个轴的正确相位即可,因此我添加了受鼠标位置(tx,ty) <0.0,1.0>
控制的相移,因此得到了最终结果:
where both coefficients are the same in between axises (weird but working I was expecting I would need to have different coefficients between axises). After this is just a matter of finding the correct phase for each axis so I add phase shift controlled by mouse position (tx,ty) <0.0,1.0>
so I got the final:
float x = sin( 25.0*p.y + 30.0*p.x + 6.28*tx) * 0.05;
float y = sin( 25.0*p.y + 30.0*p.x + 6.28*ty) * 0.05;
然后我用鼠标玩(打印其位置),直到我足够接近以匹配您想要的输出为止(这是tx=0.3477,ty=0.7812
时的状态),以便您可以进行硬编码
Then I play with mouse (printing its position) until I got close enough to match your desired output which was when tx=0.3477,ty=0.7812
so you can hard-code
float x = sin( 25.0*p.y + 30.0*p.x + 6.28*0.3477) * 0.05;
float y = sin( 25.0*p.y + 30.0*p.x + 6.28*0.7812) * 0.05;
这篇关于如何在着色器中制作波形扭曲效果?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!