【shader自娱自乐】螺旋

效果图


顶点着色器

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;
            }

老顶点着色器了


像素着色器

   fixed4 frag (v2f i) : SV_Target
   {
        fixed2 center = fixed2(0.5, 0.5);
        fixed dis = distance(i.uv, center);
        fixed angleOffset = sin(dis / 2 * 2 * UNITY_PI) * 10;//这里调整数字可以得到不同的效果
        float2x3 rotateMatrix = float2x3
        (cos(_Time.y + angleOffset), -sin(_Time.y + angleOffset), center.x * (1 - cos(_Time.y + angleOffset)) + center.y * sin(_Time.y + angleOffset),
         sin(_Time.y + angleOffset), cos(_Time.y + angleOffset), center.y * (1 - cos(_Time.y + angleOffset)) - center.x * sin(_Time.y + angleOffset));
        fixed2 uv = mul(rotateMatrix, fixed3(i.uv, 1.0));
        fixed2 direct = normalize(uv - center);
        fixed maxDis = max(abs(uv.x - 0.5), abs(uv.y - 0.5));
        float waveOffset = _Time.y / 4 * dis / maxDis;

        // sample the texture
        fixed4 col = tex2D(_MainTex, uv + waveOffset * direct);

        return col;
   }

解析:

1. 贴图像素不断往中心内坍
        fixed2 center = fixed2(0.5, 0.5);
        fixed dis = distance(i.uv, center);
        
        fixed2 direct = normalize(uv - center);
        fixed maxDis = max(abs(uv.x - 0.5), abs(uv.y - 0.5));
        float waveOffset = _Time.y / 4 * dis / maxDis;

  这一步的实现其实就是从中心向外不断同步增加uv。不过要注意的是因为uv大小是(1.0,1.0),也就是方形,所以越是接近对角线,uv增加得要越快,不然就不协调了。

2. uv绕中心点(0.5,0.5)旋转
        float2x3 rotateMatrix = float2x3
        (cos(_Time.y), -sin(_Time.y), center.x * (1 - cos(_Time.y)) + center.y * sin(_Time.y),
         sin(_Time.y), cos(_Time.y), center.y * (1 - cos(_Time.y)) - center.x * sin(_Time.y));
        
        fixed2 uv = mul(rotateMatrix, fixed3(i.uv, 1.0));
3.点睛之笔,离中心距离不同,旋转角度也有所不同
        fixed angleOffset = sin(dis / 5 * 2 * UNITY_PI) * 10;
        float2x3 rotateMatrix = float2x3
        (cos(_Time.y + angleOffset), -sin(_Time.y + angleOffset), center.x * (1 - cos(_Time.y + angleOffset)) + center.y * sin(_Time.y + angleOffset),
         sin(_Time.y + angleOffset), cos(_Time.y + angleOffset), center.y * (1 - cos(_Time.y + angleOffset)) - center.x * sin(_Time.y + angleOffset));

  这一步实现起来也很简单,就是根据离中心距离不同增加旋转角度。但不得不说的是,就是这简单的一步,结合uv的旋转,就形成了最重要的螺旋形效果


  其实这个效果有一个严重的问题,就是越到后面就会出现越多分层,到最后就会变成一条条细线。虽然我后面也做了一下优化,但也只是阻止了分层的不断增加,还是有分层的感觉。

  阻止了分层的增加,然后换了一张图,加了个逐渐增大的漩涡中心(原本就是想做漩涡的效果的)


总结

  这个效果也就三步,甚至可以理解为两步,像素的内坍以及根据中心距离的不同旋转不同的角度。这种做法也可以用到顶点着色器上,而且我感觉效果挺不错的,各位有兴趣的可以自己尝试一下,我这里也放一张相同的思想应用到顶点着色器的效果图(当然顶点不能太少,顶点少效果就没那么好了)。

你可能感兴趣的:(shader自娱自乐,unity,游戏引擎)