Unity ShaderLab特效教程 适用于贴图、sprite和ugui的2d着色器实例 代码+详解注释 【可调节缩放、力度的扭曲效果】

如果代码中有什么不清楚请查看以下基础知识

Shader基础知识
unity3d 中 七种坐标知识详解

可调节缩放、力度的扭曲效果

基本原理就是:先获得当前uv的xy夹角角度,再根据中心点到边缘的距离增加扭曲力度,然后再逆运算取得uv的xy值。

笑狗图

在这里插入图片描述

Shader "Custom/Vortex" {
    Properties {
        _MainTex ("贴图", 2D) = "white" {}
        _TexSize ("尺寸", vector) = (256, 256, 0, 0)
        _Angle  ("扭曲角度", Range(-1000, 1000)) = 45.0
        _Scale  ("缩放", Range(0, 2)) = 45.0
    }

    SubShader {
        Pass {
            //一些性能处理
            Cull Off
            //灯光
            Lighting Off
            //深度
            ZWrite Off
            //雾
            Fog { Mode Off }
            CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
                #include "UnityCG.cginc"
                sampler2D _MainTex;
                float4 _TexSize;
                float _Angle;
                float4 _Center;
                float _Scale;
                struct v2f {
                    float4 position : POSITION;
                    float2 uv : TEXCOORD0;
                } ;
                // 顶点着色器
                v2f vert(appdata_full v)
                {
                    v2f o;
                    //模型空间转裁剪空间
                    o.position = UnityObjectToClipPos (v.vertex);
                    //获取uv
                    o.uv = v.texcoord;
                    return o;
                }
                //片段着色器
                float4 frag (v2f o) : COLOR
                {
                    // _TexSize = _TexSize * (_Angle * 0.01);
                    // _Angle =  tan(_Time.y)*100;
                    //中心点 = 旋转长宽的中心点
                    float2 center = _TexSize / 2; //float2(1. /_Center.x, 1/_Center.y);
                    //中心点偏移,与size计算.  首先计算uv和texsize,将uv映射到实际宽度和高度,然后减掉中心点距离,获取到辐射边
                    float2 offset = o.uv * _TexSize - center;
                    //距离 = 三角形的那条斜边,就是受影响原型范围的半径   * _Scale; 是缩放
                    float distance = sqrt(offset.x * offset.x + offset.y * offset.y) * _Scale;
                    //atan2函数返回的是原点至点(x,y)的方位角,即与 x 轴的夹角。也可以理解为复数 x+yi 的辐角。返回值的单位为弧度,取值范围为  -pi/2~pi/2
                    //在数学坐标系中,结果为正表示从 X 轴逆时针旋转的角度,结果为负表示从 X 轴顺时针旋转的角度。
                    //获取两边的角度 取值范围为  -pi/2~pi/2
                    //原理,根据现有uv点的xy计算出夹角,在通过增加夹角,反推出变化后的xy坐标
                    float angle = atan2(offset.y, offset.x);
                    //// 距离越远,旋转值越大.值区间为(0-distance)/ _Angle
                    angle += distance / _Angle; 
                    //获取像素新的uv位置 + center 偏移    斜边*cos(角度)=底边(x),斜边*sin(角度=对边(y))
                    float2 new_uv = float2(distance * cos(angle), distance * sin(angle)) + center;
                    //逆向映射uv
                    new_uv /= _TexSize;
                    //将uv与贴图转换成颜色像素
                    return tex2D(_MainTex, new_uv);
                }
            ENDCG
        }
    }
}

发布了134 篇原创文章 · 获赞 37 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/lengyoumo/article/details/104022063
今日推荐