# 【Shader练习-扭曲直线】
可以实现类似连线,抽血等效果。
包括了以下练习内容:
- 绘制直线。
- 程序噪声 (opens new window)。
- UV扭曲。
WraplineShader.shader
Shader "Unlit/WraplineShader"
{
Properties
{
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
// 画一条直线
fixed4 getline(float2 st)
{
float l = step(0.495,st.y);
float r = step(0.505,st.y);
return max(l - r,0);
}
float hash(float2 p)
{
p = 50.0*frac( p*0.3183099 + float2(0.71,0.113));
return -1.0+2.0*frac( p.x*p.y*(p.x+p.y) );
}
// 程序噪声
float noise(float2 p)
{
int2 i = int2(floor( p ));
float2 f = frac( p );
float2 u = f*f*(3.0-2.0*f);
return lerp( lerp( hash( i + int2(0,0) ),
hash( i + int2(1,0) ), u.x),
lerp( hash( i + int2(0,1) ),
hash( i + int2(1,1) ), u.x), u.y);
}
// 分形噪声
float fractalnoise(float2 uv)
{
float f = 0.0;
uv *= 16.0;
float2x2 m = float2x2( 1.6, 1.2, -1.2, 1.6 );
f = 0.5000*noise( uv ); uv = mul(m,uv);
f += 0.2500*noise( uv ); uv = mul(m,uv);
f += 0.1250*noise( uv ); uv = mul(m,uv);
f += 0.0625*noise( uv ); uv = mul(m,uv);
return f;
}
fixed4 frag (v2f i) : SV_Target
{
float2 moveuv = i.uv + float2(_Time.y * 0.25,0);
// 静止的噪声
float noise = fractalnoise(i.uv);
// 移动的噪声
float mnoise = fractalnoise(moveuv);
// uv扰动
float2 noiseuv = frac(i.uv + float2(mnoise*0.01,mnoise*0.01) + float2(noise*0.01,noise*0.01));
// 根据扰动的uv来生成扭曲直线
return getline(noiseuv);
}
ENDCG
}
}
}