一:前面的心情
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的,一个是本文背面使用的