本文实例为大家分享了unityshader3实现2d描边效果的具体代码,供大家参考,具体内容如下
1.
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
|
shader "custom/edge" { properties { _maintex ( "texture" , 2d) = "white" {} _offsetuv ( "offsetuv" , range(0, 1)) = 0.1 _edgecolor ( "edgecolor" , color) = (1, 0, 0, 1) _alphatreshold ( "treshold" , range(0, 1)) = 0.5 } subshader { tags { "queue" = "transparent" } blend srcalpha oneminussrcalpha pass { cgprogram #pragma vertex vert #pragma fragment frag #include "unitycg.cginc" struct appdata { float4 vertex : position; fixed2 uv : texcoord0; }; struct v2f { float4 vertex : sv_position; fixed2 uv[5] : texcoord0; }; sampler2d _maintex; float4 _maintex_st; fixed _offsetuv; fixed4 _edgecolor; fixed _alphatreshold; v2f vert (appdata v) { v2f o; o.vertex = mul(unity_matrix_mvp, v.vertex); o.uv[0] = v.uv; o.uv[1] = v.uv + fixed2(0, _offsetuv); //up o.uv[2] = v.uv + fixed2(-_offsetuv, 0); //left o.uv[3] = v.uv + fixed2(0, -_offsetuv); //bottom o.uv[4] = v.uv + fixed2(_offsetuv, 0); //right return o; } fixed4 frag (v2f i) : sv_target { fixed4 original = tex2d(_maintex, i.uv[0]); fixed alpha = original.a; fixed p1 = tex2d(_maintex, i.uv[1]).a; fixed p2 = tex2d(_maintex, i.uv[2]).a; fixed p3 = tex2d(_maintex, i.uv[3]).a; fixed p4 = tex2d(_maintex, i.uv[4]).a; alpha = p1 + p2 + p3 + p4 + alpha; alpha /= 5; if (alpha < _alphatreshold) original.rgb = _edgecolor.rgb; return original; } endcg } } } |
2.
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
|
shader "custom/edge" { properties { _edge ( "edge" , range(0, 0.2)) = 0.043 _edgecolor ( "edgecolor" , color) = (1, 1, 1, 1) _maintex ( "maintex" , 2d) = "white" {} } subshader { pass { cgprogram #pragma vertex vert #pragma fragment frag #include "unitycg.cginc" fixed _edge; fixed4 _edgecolor; sampler2d _maintex; struct appdata { float4 vertex : position; fixed2 uv : texcoord0; }; struct v2f { float4 vertex : sv_position; float4 objvertex : texcoord0; fixed2 uv : texcoord1; }; v2f vert (appdata v) { v2f o; o.vertex = mul(unity_matrix_mvp, v.vertex); o.objvertex = v.vertex; o.uv = v.uv; return o; } fixed4 frag (v2f i) : sv_target { fixed x = i.uv.x; fixed y = i.uv.y; if ((x < _edge) || (abs(1 - x) < _edge) || (y < _edge) || (abs(1 - y) < _edge)) { return _edgecolor * abs(cos(_time.y)); } else { fixed4 color = tex2d(_maintex, i.uv); return color; } //return i.objvertex; //return fixed4(i.uv, 0, 1); } endcg } } } |
3.如下图,左边是一个image,右边是一个plane。
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
|
// upgrade note: replaced 'mul(unity_matrix_mvp,*)' with 'unityobjecttoclippos(*)' shader "custom/edge" { properties { _edge ( "edge" , range(0, 0.2)) = 0.043 _edgecolor ( "edgecolor" , color) = (1, 1, 1, 1) _flowcolor ( "flowcolor" , color) = (1, 1, 1, 1) _flowspeed ( "flowspeed" , range(0, 10)) = 3 _maintex ( "maintex" , 2d) = "white" {} } subshader { tags { "queue" = "transparent" "rendertype" = "transparent" "ignoreprojector" = "true" } pass { zwrite off blend srcalpha oneminussrcalpha cgprogram #pragma vertex vert #pragma fragment frag #include "unitycg.cginc" fixed _edge; fixed4 _edgecolor; fixed4 _flowcolor; float _flowspeed; sampler2d _maintex; struct appdata { float4 vertex : position; fixed2 uv : texcoord0; }; struct v2f { float4 vertex : sv_position; fixed2 uv : texcoord1; }; v2f vert (appdata v) { v2f o; o.vertex = unityobjecttoclippos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : sv_target { fixed x = i.uv.x; fixed y = i.uv.y; if ((x < _edge) || (abs(1 - x) < _edge) || (y < _edge) || (abs(1 - y) < _edge)) { //点旋转公式: //假设对图片上任意点(x,y),绕一个坐标点(rx0,ry0)逆时针旋转a角度后的新的坐标设为(x0,y0),有公式: //x0 = (x - rx0) * cos(a) - (y - ry0) * sin(a) + rx0 ; //y0 = (x - rx0) * sin(a) + (y - ry0) * cos(a) + ry0 ; float a = _time.y * _flowspeed; float2 rotuv; x -= 0.5; y -= 0.5; rotuv.x = x * cos(a) - y * sin(a) + 0.5; rotuv.y = x * sin(a) + y * cos(a) + 0.5; fixed temp = saturate(rotuv.x - 0.5); //-0.5作用是调整流动颜色的比例 return _edgecolor * (1 - temp) + _flowcolor * temp; } else { //fixed4 color = tex2d(_maintex, i.uv); return fixed4(1, 1, 1, 0); } } endcg } } } |
4.通过观察上面的效果图,会发现右边的plane出现了锯齿。而解决锯齿一般的方法就是做模糊处理,模糊处理一般又有贴图处理和代码处理之分,这里使用的是贴图处理。贴图处理需要提供一张边界模糊的贴图。
如上图,左下是内边反锯齿的图,右上是未经处理的图。
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
|
// upgrade note: replaced 'mul(unity_matrix_mvp,*)' with 'unityobjecttoclippos(*)' shader "custom/edge2" { properties { _edge ( "edge" , range(0, 0.2)) = 0.043 _edgecolor ( "edgecolor" , color) = (1, 1, 1, 1) _flowcolor ( "flowcolor" , color) = (1, 1, 1, 1) _flowspeed ( "flowspeed" , range(0, 10)) = 3 _maintex ( "maintex" , 2d) = "white" {} } subshader { tags { "queue" = "transparent" "rendertype" = "transparent" "ignoreprojector" = "true" } pass { zwrite off blend srcalpha oneminussrcalpha cgprogram #pragma vertex vert #pragma fragment frag #include "unitycg.cginc" fixed _edge; fixed4 _edgecolor; fixed4 _flowcolor; float _flowspeed; sampler2d _maintex; struct appdata { float4 vertex : position; fixed2 uv : texcoord0; }; struct v2f { float4 vertex : sv_position; fixed2 uv : texcoord1; }; v2f vert (appdata v) { v2f o; o.vertex = unityobjecttoclippos(v.vertex); o.uv = v.uv; return o; } fixed4 frag (v2f i) : sv_target { fixed4 color = tex2d(_maintex, i.uv); float alpha = color.a; fixed x = i.uv.x; fixed y = i.uv.y; float a = _time.y * _flowspeed; float2 rotuv; x -= 0.5; y -= 0.5; rotuv.x = x * cos(a) - y * sin(a) + 0.5; rotuv.y = x * sin(a) + y * cos(a) + 0.5; fixed temp = saturate(rotuv.x - 0.5); //-0.5作用是调整流动颜色的比例 fixed4 finalcolor = _edgecolor * (1 - temp) + _flowcolor * temp; finalcolor.a = alpha; return finalcolor; } endcg } } } |
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.csdn.net/lyh916/article/details/51487918