轮廓边 二 使用膨胀扩充

一:前面的心情

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

改变自己
原文地址:https://www.cnblogs.com/sun-shadow/p/4976392.html