一:前面的心情
3.最近发现zdd博客一直在更新,坚持了十年以上了。
二:本文内容
1.本次根据膨胀微小的范围,达到绘制轮廓边的效果,原理和官网 美国大兵膨胀一样。
2.test了一下,对box适用,对单个plane并不适用。原因是单个plane,xy坐标虽膨胀了,假设膨胀并CULLfront的plane为B,原plane为A,B并没有影响到A,也就是说,本文方法只适用于封闭的形状。关键还是o.pos.xy += normalOffset*_threshold*o.pos.z;
一句话,本文轮廓边是其他面片膨胀造成的。
虚线网格为cull front,背面为边缘色
三:参考:
膨胀描边:http://blog.csdn.net/cubesky/article/details/38588723
normal坐标变幻:http://blog.csdn.net/pizi0475/article/details/7932913
四:代码及步骤:
Shader "Custom/outLineTest" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _threshold("outLine threshold ",float)=0.005 } SubShader{ Pass{ Fog{Mode Off} Cull Front //对背面顶点进行扩充 ZWrite On CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" uniform float _threshold; struct appdata{ float4 vertex : POSITION; float3 normal : NORMAL; }; struct v2f1{ float4 pos :SV_POSITION; float4 color: COLOR; }; v2f1 vert(appdata inV) { v2f1 o; o.pos = mul(UNITY_MATRIX_MVP,inV.vertex); float3 norm = mul ((float3x3)UNITY_MATRIX_IT_MV, inV.normal);//将normal转化到viewSpace float2 normalOffset = TransformViewToProjection(norm.xy); //将normal转化到NDC空间 o.pos.xy += normalOffset*_threshold*o.pos.z;//对xy进行微量扩充 o.color = float4(0,1,0,1); return o; } float4 frag(v2f1 inV):SV_Target { return inV.color; } ENDCG } } Fallback off }
五:注意点:
1.normal的空间变换和vertex的区别,是逆的转置矩阵
2.扩充xy坐标,并伴随z深度值进行变化,z值在0-1之间,z越大,扩充越厉害,
由于z在NDC中是近裁剪0 远裁剪1,即越远的轮廓扩充范围越大,这也合理
3.注意单个plane,本文其实是其他面片的cull front影响一个面片。。
4.不要忘记Mesh render中Material的size要设置成2,一个是正面render的,一个是本文背面使用的