UnityShader3实现彩光效果

 更新时间:2019年03月03日 08:54:47   作者:宏哥1995  
这篇文章主要为大家详细介绍了UnityShader3实现彩光效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了UnityShader3实现彩光效果展示的具体代码,供大家参考,具体内容如下

参考链接: 【OpenGL】Shader实例分析(八)- 彩色光圈

效果图:

这里我把它分三部分实现: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 vertex : SV_POSITION;
 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
 { 
 float4 vertex : SV_POSITION;
 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
 }
 }
}

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • C#使用时序数据库InfluxDB的教程详解

    C#使用时序数据库InfluxDB的教程详解

    InfluxDB是一个开源的时序数据库,可以自动处理时间序列数据,这篇文章主要为大家详细介绍了C#如何使用InfluxDB,感兴趣的小伙伴可以跟随小编一起了解下
    2023-11-11
  • C#汉字转拼音实例(支持多音字)

    C#汉字转拼音实例(支持多音字)

    几年前就在网上看到过汉字转拼音的程序,大都就是按汉字的编码转换,单字对应的算法实现的。但是都有一个共同的缺点,不能支持多音字。本篇文章主要介绍了C#汉字转拼音实例(支持多音字),有兴趣的可以了解一下。
    2016-12-12
  • C#检查远程或本地磁盘使用率

    C#检查远程或本地磁盘使用率

    要检查磁盘的使用情况确定程序放哪个服务器和清理垃圾,所以写个小程序帮忙检查。本文给大家介绍C#检查远程或本地磁盘使用率的相关知识,感兴趣的朋友一起学习吧
    2016-04-04
  • Unity中 ShaderGraph 实现超级炫酷的溶解效果入门级教程

    Unity中 ShaderGraph 实现超级炫酷的溶解效果入门级教程

    这篇文章主要介绍了Unity中的 ShaderGraph 实现超级炫酷的溶解效果入门级教程,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-07-07
  • C#桥接模式完整实例

    C#桥接模式完整实例

    这篇文章主要介绍了C#桥接模式,以实例形式较为详细的分析了C#桥接模式的实现原理与相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-07-07
  • 深入了解c# 迭代器和列举器

    深入了解c# 迭代器和列举器

    这篇文章主要介绍了c# 迭代器和列举器的相关资料,帮助大家更好的理解和学习C#,感兴趣的朋友可以了解下
    2020-08-08
  • WPF ComboBox获取当前选择值的实例详解

    WPF ComboBox获取当前选择值的实例详解

    这篇文章主要介绍了WPF ComboBox获取当前选择值的实例详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2021-01-01
  • .NET创建、删除、复制文件夹及其子文件的实例方法

    .NET创建、删除、复制文件夹及其子文件的实例方法

    .NET创建、删除、复制文件夹及其子文件的实例方法,需要的朋友可以参考一下
    2013-03-03
  • C#中XmlTextWriter读写xml文件详细介绍

    C#中XmlTextWriter读写xml文件详细介绍

    .NET中包含了很多支持XML的类,这些类使得程序员使用XML编程就如同理解XML文件一样简单。在这篇文章中,我将给出这样的一个类的使用示例,这个类就是XmlTextWriter类
    2013-04-04
  • c# winform多线程死循环踩坑

    c# winform多线程死循环踩坑

    本文主要介绍了c# winform多线程死循环踩坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-12-12

最新评论