UnityShader3实现彩光效果

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

UnityShader3实现彩光效果
本⽂实例为⼤家分享了UnityShader3实现彩光效果展⽰的具体代码,供⼤家参考,具体内容如下
参考链接:
效果图:
这⾥我把它分三部分实现:1.彩⾊ 2.光圈 3.动画
1.先实现彩⾊效果。

分析⼀下那张彩⾊图,它是以中⼼为原点的,然后颜⾊分为三部分,如下图。

当⾓度为90度时,蓝⾊最多;当⾓度为-150度时,红⾊最多;当⾓度为-30度时,绿⾊最多。

然后其他地⽅就是三⾊混合。

Shader "Custom/Colors"
{
Properties
{
_AngleRange ("AngleRange", Range(60, 120)) = 60
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#define PI 3.142
struct appdata
{
float4 vertex : POSITION;
};
struct v2f
float4 scrPos : TEXCOORD0;
};
half _AngleRange;
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.scrPos = ComputeScreenPos(o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//范围在(0, 1)
float2 wcoord = i.scrPos.xy / i.scrPos.w;
//映射到(-1, 1),即屏幕中⼼为(0, 0)
wcoord = wcoord * 2 - 1;
//atan2(y, x):反正切,y/x的反正切范围在[-π, π]内
float radian = atan2(wcoord.y, wcoord.x);
//1度(°)=0.017弧度(rad)
//1弧度(rad)=57.29578度(°)
float angle = radian * 57.3;
//映射到(0, 360)
if(angle < 0) angle = 360 + angle;
fixed b = 1 - saturate(abs(angle - 90) / _AngleRange);
fixed g;
if(angle > 180) g = 1 - saturate(abs(angle - 330) / _AngleRange);
else g = 1 - saturate((angle + 30) / _AngleRange);
fixed r = 1 - saturate(abs(angle - 210) / _AngleRange);
return fixed4(r, g, b, 1);
}
ENDCG
}
}
}
2.先说⼀下1 / (xxx)这个式⼦的强⼤,它实现的效果,往往会带有光晕效果。

其中第六个就是我们想要实现的光圈效果。

Shader "Custom/Test"
{
Properties
{
_Value ("Value", Range(1, 50)) = 1
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
float2 uv : TEXCOORD0;
};
half _Value;
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//映射到(-1, 1),使其中⼼点为原点
float2 uv = i.uv * 2 - float2(1, 1);
float v;
//v = 1 / abs(_Value * uv.y);//1
//v = 1 / abs(_Value * (uv.y + uv.x));//2
//v = 1 / abs(_Value * (uv.y + 2 * uv.x));//3
//v = 1 / abs(_Value * (abs(uv.y) + abs(uv.x)));//4
//v = 1 / abs(_Value * length(uv));//5
//v = 1 / abs(_Value * abs(length(uv) - 0.5));//6
v = 1 / abs(_Value * abs(uv.x / uv.y));//7 x越⼩y越⼤,则越亮 return fixed4(v, v, v, 1);
}
ENDCG
}
}
}
3.动画。

这⾥我做的效果是基于⾓度的光线间隔效果,⾸先当然就是计算⾓度了,间隔的实现就是fmod和step的使⽤。

Shader "Custom/Test"
{
Properties
{
_Width ("Width", Range(30, 90)) = 45
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
};
half _Width;
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//映射到(-1, 1),使其中⼼点为原点
float2 uv = i.uv * 2 - float2(1, 1);
float a = atan2(uv.y, uv.x);
a *= 57.3;
if(a < 0) a += 360;
float b = fmod(a + _Time.y * 20, _Width);
b = step(0.5 * _Width, b);
return fixed4(b, b, b, 1);
}
ENDCG
}
}
}
> 4.最后当然就是将它们揉在⼀起了。

Shader "Custom/Colors"
{
Properties
{
_AngleRange ("AngleRange", Range(60, 120)) = 60
_Width ("Width", Range(30, 90)) = 45
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#define PI 3.142
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float4 vertex : SV_POSITION;
float4 scrPos : TEXCOORD0;
float2 uv : TEXCOORD1;
};
half _AngleRange;
half _Width;
v2f vert (appdata v)
{
v2f o;
o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
o.scrPos = ComputeScreenPos(o.vertex);
o.uv = v.uv;
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//1.彩⾊
//范围在(0, 1)
float2 wcoord = i.scrPos.xy / i.scrPos.w;
//映射到(-1, 1),即屏幕中⼼为(0, 0)
wcoord = wcoord * 2 - 1;
//atan2(y, x):反正切,y/x的反正切范围在[-π, π]内
float radian = atan2(wcoord.y, wcoord.x);
//1度(°)=0.017弧度(rad)
//1弧度(rad)=57.29578度(°)
float angle = radian * 57.3;
//映射到(0, 360)
if(angle < 0) angle = 360 + angle;
fixed b = 1 - saturate(abs(angle - 90) / _AngleRange);
fixed g;
if(angle > 180) g = 1 - saturate(abs(angle - 330) / _AngleRange);
else g = 1 - saturate((angle + 30) / _AngleRange);
fixed r = 1 - saturate(abs(angle - 210) / _AngleRange);
//2.光圈
//映射到(-1, 1),使其中⼼点为原点
float2 uv = i.uv * 2 - float2(1, 1);
float v = 1 / abs(30 * abs(length(uv) - 0.3));
//3.转动
float a = atan2(uv.y, uv.x);
a *= 57.3;
if(a < 0) a += 360;
float aa = fmod(a + _Time.y * 20, _Width);
aa = step(0.5 * _Width, aa);
//////////////////////
//////////////////////
if(length(uv) < 0.3) return fixed4(0, 0, 0, 1);
return fixed4(r, g, b, 1) * aa + fixed4(v, v, v, 1);
}
ENDCG
}
}
}
以上就是本⽂的全部内容,希望对⼤家的学习有所帮助,也希望⼤家多多⽀持。

相关文档
最新文档