UnityShader3实现2D描边效果
程序员文章站
2023-12-10 08:56:04
本文实例为大家分享了unityshader3实现2d描边效果的具体代码,供大家参考,具体内容如下
1.
shader "custom/edge"
{...
本文实例为大家分享了unityshader3实现2d描边效果的具体代码,供大家参考,具体内容如下
1.
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.
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。
// 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出现了锯齿。而解决锯齿一般的方法就是做模糊处理,模糊处理一般又有贴图处理和代码处理之分,这里使用的是贴图处理。贴图处理需要提供一张边界模糊的贴图。
如上图,左下是内边反锯齿的图,右上是未经处理的图。
// 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 } } }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。