一些通过uv纹理坐标实现的简单shader(二)

    上一篇我们实现了简单的波动效果,这一篇就尝试一下扭曲的效果,如下图:
一些通过uv纹理坐标实现的简单shader(二)_第1张图片
    同样是使用unity的顶点与片段着色器,首先是一些准备工作:

Shader "Custom/Custom-Twirl" {
    Properties {
        _MainTex ("Base (RGB)", 2D) = "white" {}
    }
    SubShader {
        Tags { "RenderType"="Opaque" }
        LOD 200

        Pass
        {

            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"

            sampler2D _MainTex;
            float4 _MainTex_ST;

            struct v2f
            {
                float4 pos : POSITION;
                float2 uv : TEXCOORD0;
            };

            v2f vert(appdata_full v)
            {

                v2f o;
                o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
                o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                return o;

            }

            float4 frag(v2f i) : COLOR
            {      
//to do ...
            }

            ENDCG
        }
    }
    FallBack "Diffuse"
}

    为了得到上图的效果, 很明显,我们需要将图片的像素绕中心点进行旋转,而且像素位置距离 中心点越远,其旋转角度越大,为此,我们在片段着色器进行如下处理:

    float4 frag(v2f i) : COLOR
    {
        float2 tc = i.uv;
        tc -= float2(0.5,0.5);
        float d= length(tc);//与中点的距离
        float originAngle = acos(dot(tc, float2(1, 0))/d);//与x轴的夹角,还有其他方法,这个方法需要注意角度的正负
        if (tc.y < 0) {
            originAngle = -originAngle;
        }
        float angle =originAngle+ d * _Slider;/*d * _Slider是旋转角度,这里与距中点距离成比例,也可以是其他关系
            _Slider是用来控制旋转程度的参数,需要先在属性里定义一下  */
        tc = float2(0.5+d*cos(angle),0.5+d*sin(angle));
        float3 color = tex2D(_MainTex, tc).rgb;
        return float4(color, 1.0);
    }

    其中我们定义旋转角度与距离成正比,当然也可以由其他关系,其结果如下:
一些通过uv纹理坐标实现的简单shader(二)_第2张图片
    这里我们发现一个问题,如果图形不是圆的,其边缘并不适合上述处理,需要做其他调整,在unity的inspector面板中,将图片的wrap mode 作如下修改,则可恢复正常。
一些通过uv纹理坐标实现的简单shader(二)_第3张图片
一些通过uv纹理坐标实现的简单shader(二)_第4张图片

ML

你可能感兴趣的:(unity3d)