需要明确Webgl Shaders的配置和参数才能达到预期的效果

时间:2017-11-16 05:57:18

标签: javascript typescript webgl shader 2d-games

我希望从上到下的方向对水喷片应用波浪效果,使其看起来像动画一样。我从互联网上获得了一些代码,但它以随机的方式创建了一些效果。我想按照我的要求控制它。Below is the image on which I want to apply wave effects下面是代码:

function CustomFilter(customSprite, ambientColor, resolution) {
        PIXI.Filter.call(
            this,
            null,
            (
                `
               varying vec2 vTextureCoord;
            uniform sampler2D uSampler;
            uniform float u_ctime;
            const int iterations = 1;
            const float view = 3.;
            void main()
            {
                    vec2 fragCoord = vTextureCoord;
                    vec2 iResolution = vec2(1.0,1.0);
                    float iGlobalTime = u_ctime;
                vec2 uv = fragCoord.xy;
                uv *= view;
                for (int i = 0; i < iterations; i++) {
                float ang = atan(uv.y+cos(uv.y*2.+iGlobalTime)*.5,
                uv.y+sin(uv.y*2.+iGlobalTime)*.5)-length(uv)*.1;
                float sn = sin(ang);

                 mat2 m = mat2(sn,sn,sn,sn);
                 uv = uv*.15-abs(uv*.5*m);
                }

                float d = length(mod(uv,1.)-.5)-.4;

                d *= 20.;
                vec4 FragColor = vec4( sin(uv.x*d), sin(d+.5346), -sin(d+uv.x*1.63), 1. )*.5;
                vec2 u_Scale = vec2(0.0,0.07)*sin(u_ctime);
                vec3 displace = FragColor.rba;
                displace.xy *= displace.z * u_Scale*(0.5-fragCoord.x);
                gl_FragColor = texture2D( uSampler, vTextureCoord + displace.xy );
            }

            `
            )

        );

1 个答案:

答案 0 :(得分:0)

波浪效果的基础功能是sincos,如果你仔细观察,你会发现你的超级复杂着色器已经充满了它。矛盾的是,与常规波相比,实现随机性的方式更为复杂。

例如,要沿X(水平)轴绘制波形,并在Y(垂直)轴上进行变化,您将使用此函数:

let frequency = 2.0;
let amplitude = 1.0;
let y_base = 0.0;
for(x = 0.0; x < 1.0; x += 0.01) {
  point.x = x;
  point.y = y_base + (sin(x * frequency) * amplitude);
}

很简单,不是吗?您只需将此概念应用于着色器,例如,使用纹理采样。因此,如果您想要,例如,沿X轴创建波浪效果,您可以使用类似的东西:

 float f = 5.0;
 float a = 0.05;
 vec4 waved = texture2D(sampler, vec2(coord.x, coord.y+(sin(coord.x*f)*a)));

如果你想添加一些动画,你只需添加一种时间变量(在你的着色器中,这当前是u_ctime),伪代码将如下所示:

let time = clock();
let pitch = 0.5;
let frequency = 2.0;
let amplitude = 1.0;
let y_base = 0.0;

for(x = 0.0; x < 1.0; x += 0.01) {
  point.x = x;
  point.y = y_base + (sin((time * pitch) + x * frequency) * amplitude);
}

另请参阅:https://en.wikipedia.org/wiki/Sine#Unit_circle_definition