服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C# - UnityShader3实现彩光效果

UnityShader3实现彩光效果

2022-07-09 09:19宏哥1995 C#

这篇文章主要为大家详细介绍了UnityShader3实现彩光效果,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

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

效果图:

UnityShader3实现彩光效果

这里我把它分三部分实现:1.彩色 2.光圈 3.动画

UnityShader3实现彩光效果UnityShader3实现彩光效果

1.先实现彩色效果。分析一下那张彩色图,它是以中心为原点的,然后颜色分为三部分,如下图。当角度为90度时,蓝色最多;当角度为-150度时,红色最多;当角度为-30度时,绿色最多。然后其他地方就是三色混合。

UnityShader3实现彩光效果

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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
 }
 }
}

UnityShader3实现彩光效果

2.先说一下1 / (xxx)这个式子的强大,它实现的效果,往往会带有光晕效果。其中第六个就是我们想要实现的光圈效果。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
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
 }
 }
}

UnityShader3实现彩光效果

UnityShader3实现彩光效果

UnityShader3实现彩光效果

UnityShader3实现彩光效果

UnityShader3实现彩光效果

UnityShader3实现彩光效果

UnityShader3实现彩光效果

3.动画。这里我做的效果是基于角度的光线间隔效果,首先当然就是计算角度了,间隔的实现就是fmod和step的使用。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
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
 }
 }
}

>UnityShader3实现彩光效果

4.最后当然就是将它们揉在一起了。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
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
 }
 }
}

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

原文链接:https://blog.csdn.net/lyh916/article/details/51913146

延伸 · 阅读

精彩推荐
  • C#c#通用登录模块分享

    c#通用登录模块分享

    这是一款简单的ASP.NETC#注册登录模块制作思路,非常简单实用,虽然没怎么考虑登陆的安全性,但作为C#的朋友学习交流使用。...

    C#教程网6332021-11-29
  • C#C#中的委托数据类型简介

    C#中的委托数据类型简介

    委托是一个类型安全的对象,它指向程序中另一个以后会被调用的方法(或多个方法)。通过本文给大家介绍C#中的委托数据类型简介,对c委托类型相关知...

    崎岖行者4422021-11-15
  • C#C#简单读取主机上所有进程的方法

    C#简单读取主机上所有进程的方法

    这篇文章主要介绍了C#简单读取主机上所有进程的方法,涉及C#进程的遍历读取操作相关实现技巧,需要的朋友可以参考下...

    Quber6112021-12-02
  • C#WinForm实现程序一段时间不运行自动关闭的方法

    WinForm实现程序一段时间不运行自动关闭的方法

    这篇文章主要介绍了WinForm实现程序一段时间不运行自动关闭的方法,涉及WinForm计时器及进程操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下...

    我心依旧11102021-10-22
  • C#C#编写COM组件的方法分析

    C#编写COM组件的方法分析

    这篇文章主要介绍了C#编写COM组件的方法,结合实例形式分析了C#编写COM组件的具体步骤与相关实现技巧,需要的朋友可以参考下...

    廖先生6242022-01-10
  • C#C#警惕匿名方法造成的变量共享实例分析

    C#警惕匿名方法造成的变量共享实例分析

    这篇文章主要介绍了C#警惕匿名方法造成的变量共享,以实例形式分析了C#的匿名方法造成变量共享的原因及对应的解决方法,具有一定参考借鉴价值,需要的朋...

    老赵11132021-11-02
  • C#C#编程自学之数据类型和变量三

    C#编程自学之数据类型和变量三

    C#语言类型系统提出的一个核心概念装箱(boxing)拆箱(unboxing)。装箱和取消装箱的概念是C#的类型系统的核心。它在“值类型”和“引用类型”之间的架...

    C#教程网6712021-10-29
  • C#谈C# using的用法与好处

    谈C# using的用法与好处

    这篇文章主要为大家详细介绍了C# using的用法与好处,具体分析了using指令调用的Dispose()方法,感兴趣的朋友可以参考一下...

    net小伙10862021-11-21