如果代码中有什么不清楚请查看以下基础知识
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
}
}
}