UNITY随记(八) SHADER实现立方体CUBE显示边框,描边

UNITY随记(八) SHADER实现立方体CUBE显示边框,描边_第1张图片

	Shader "Vitens/CubeOutline"
	{
	    Properties
	    {
			_Color("Color", color) = (1,1,1,1)
			_Width("Width", range(0,0.5)) = 0.1
	    }
	    SubShader
	    {
			Tags { "Queue"="Transparent" }
			Pass {

	  //如果要显示背面的线框,取消下面两个注释即可
			//cull off
			//ZWrite off
			blend srcalpha oneminussrcalpha
			CGPROGRAM

			#pragma vertex vert
			#pragma fragment frag
			#include "UnityCG.cginc"
			uniform sampler2D _MainTex;
			uniform float4 _MainTex_ST;
			fixed4 _Color;
			fixed _Width;

			struct a2v {
				float4 vertex : POSITION;
				float2 uv : TEXCOORD0;
			};

			struct v2f {
				float4 pos : SV_POSITION;
				float2 uv : TEXCOORD0;
			};

			v2f vert(a2v v) {
				v2f o;

				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = v.uv;

				return o;
			}

			float4 frag(v2f i) : SV_Target {

				fixed4 col = fixed4(0,0,0,0);//Cube的基础颜色
				
				col += saturate(step(i.uv.x, _Width) + step(1 - _Width, i.uv.x) + step(i.uv.y, _Width) + step(1 - _Width, i.uv.y)) * _Color;

				//if (i.uv.x < _Width || i.uv.x > 1 - _Width || i.uv.y < _Width || i.uv.y > 1 - _Width) 
				//{
				//	col = _Color;
				//}

				return  col;
			}

			ENDCG
		}
    }
}

红色范围则是我们要找的边缘附近的部分,比如这里的边长是0.1,则边缘范围就是

uv.x < 0.1 || uv.x > 1 - 0.1 || uv.y < 0.1 || uv.y > 1 - 0.1

注意此效果仅仅针对部分模型生效,比如unity内置的立方体Cube,因为采用的实现方式比较依赖顶点UV值。

实现思路:

通过UV值判断,处在立方体边的边缘附近(接近0和接近1的部分)的部分可见,而其他部分透明度设为0,作为不可见部分,而具体要怎么判断是否在边附近。要从内置的cube顶点参数来找线索了,如果仅仅是为了显示一个立方体模型的话,用八个顶点就够了,也就是说立方体的每个角就一个顶点,一个面两个三角形就总共十二个三角形就搞定,的确,如果自己手动尝试构造一个立方体Mesh八个顶点是足够的,但是如果需要贴图,并且要求每个面都能正常且完整的显示这张贴图的话,就会发现八个顶点是基本上达不到要求的(就是立方体的每个面都像一个Quad一样的显示贴图,反正我是没有摸索出这样的妙招),可以观察到unity内置的Cube构造的立方体Mesh用了24个顶点,才能达到立方体的每个面都像一个Quad一样的显示贴图,当然多出来的顶点不仅仅是解决UV问题,还有normal等,这里用不到所以只关注UV即可。

在这里插入图片描述

额,说了这么多其实就是为了引出一个结论,Cube的Mesh的每个面的UV情况其实就是和一个Quad是基本一致的,也和普通的UI控件的Image一样,均匀的沿着U和V方向从0->1,如果不是很确定的话可以用代码获取到Mesh对象,并打印他的顶点中的UV即可验证。

你可能感兴趣的:(unity,游戏引擎)