#pragma target 5.0 #include "UnityCG.cginc" //------------------------------------------------------------------------------------------------------------------------------------------------------------- float4 _Color; float g_flOutlineWidth; float g_flCornerAdjust; float4x4 _InverseRotation; float4 _GlobalClipCenter; float4 _GlobalClipExtents; //------------------------------------------------------------------------------------------------------------------------------------------------------------- struct VS_INPUT { float4 vPositionOs : POSITION; float3 vNormalOs : NORMAL; }; struct PS_INPUT { float4 vPositionOs : TEXCOORD0; float3 vNormalOs : TEXCOORD1; float3 clipPos : TEXCOORD2; float4 vPositionPs : SV_POSITION; }; //------------------------------------------------------------------------------------------------------------------------------------------------------------- PS_INPUT MainVs(VS_INPUT i) { PS_INPUT o; o.vPositionOs.xyzw = i.vPositionOs.xyzw; o.vNormalOs.xyz = i.vNormalOs.xyz; #if UNITY_VERSION >= 540 o.vPositionPs = UnityObjectToClipPos(i.vPositionOs.xyzw); #else o.vPositionPs = UnityObjectToClipPos(i.vPositionOs.xyzw); #endif o.clipPos = (float3)0; return o; } PS_INPUT MainVsClip(VS_INPUT i) { PS_INPUT o; o.vPositionOs.xyzw = i.vPositionOs.xyzw; o.vNormalOs.xyz = i.vNormalOs.xyz; #if UNITY_VERSION >= 540 o.vPositionPs = UnityObjectToClipPos(i.vPositionOs.xyzw); #else o.vPositionPs = UnityObjectToClipPos(i.vPositionOs.xyzw); #endif o.clipPos = mul(_InverseRotation, mul(unity_ObjectToWorld, i.vPositionOs)); return o; } //------------------------------------------------------------------------------------------------------------------------------------------------------------- PS_INPUT Extrude(PS_INPUT vertex) { PS_INPUT extruded = vertex; // Offset along normal in projection space float3 vNormalVs = mul((float3x3)UNITY_MATRIX_IT_MV, vertex.vNormalOs.xyz); float2 vOffsetPs = TransformViewToProjection(vNormalVs.xy); vOffsetPs.xy = normalize(vOffsetPs.xy); // Calculate position #if UNITY_VERSION >= 540 extruded.vPositionPs = UnityObjectToClipPos(vertex.vPositionOs.xyzw); #else extruded.vPositionPs = UnityObjectToClipPos(vertex.vPositionOs.xyzw); #endif extruded.vPositionPs.xy += vOffsetPs.xy * extruded.vPositionPs.w * g_flOutlineWidth; return extruded; } //------------------------------------------------------------------------------------------------------------------------------------------------------------- [maxvertexcount(18)] void ExtrudeGs(triangle PS_INPUT inputTriangle[3], inout TriangleStream outputStream) { float3 a = normalize(inputTriangle[0].vPositionOs.xyz - inputTriangle[1].vPositionOs.xyz); float3 b = normalize(inputTriangle[1].vPositionOs.xyz - inputTriangle[2].vPositionOs.xyz); float3 c = normalize(inputTriangle[2].vPositionOs.xyz - inputTriangle[0].vPositionOs.xyz); inputTriangle[0].vNormalOs = inputTriangle[0].vNormalOs + normalize(a - c) * g_flCornerAdjust; inputTriangle[1].vNormalOs = inputTriangle[1].vNormalOs + normalize(-a + b) * g_flCornerAdjust; inputTriangle[2].vNormalOs = inputTriangle[2].vNormalOs + normalize(-b + c) * g_flCornerAdjust; PS_INPUT extrudedTriangle0 = Extrude(inputTriangle[0]); PS_INPUT extrudedTriangle1 = Extrude(inputTriangle[1]); PS_INPUT extrudedTriangle2 = Extrude(inputTriangle[2]); outputStream.Append(inputTriangle[0]); outputStream.Append(extrudedTriangle0); outputStream.Append(inputTriangle[1]); outputStream.Append(extrudedTriangle0); outputStream.Append(extrudedTriangle1); outputStream.Append(inputTriangle[1]); outputStream.Append(inputTriangle[1]); outputStream.Append(extrudedTriangle1); outputStream.Append(extrudedTriangle2); outputStream.Append(inputTriangle[1]); outputStream.Append(extrudedTriangle2); outputStream.Append(inputTriangle[2]); outputStream.Append(inputTriangle[2]); outputStream.Append(extrudedTriangle2); outputStream.Append(inputTriangle[0]); outputStream.Append(extrudedTriangle2); outputStream.Append(extrudedTriangle0); outputStream.Append(inputTriangle[0]); } //------------------------------------------------------------------------------------------------------------------------------------------------------------- fixed4 MainPs(PS_INPUT IN) : SV_Target { return _Color; } //------------------------------------------------------------------------------------------------------------------------------------------------------------- fixed4 NullPs(PS_INPUT IN) : SV_Target { return float4(1.0, 0.0, 1.0, 1.0); } //------------------------------------------------------------------------------------------------------------------------------------------------------------- fixed4 MainPsClip(PS_INPUT IN) : SV_Target { float3 diff = abs(IN.clipPos - _GlobalClipCenter); if (diff.x > _GlobalClipExtents.x || diff.y > _GlobalClipExtents.y || diff.z > _GlobalClipExtents.z) discard; return _Color; } //------------------------------------------------------------------------------------------------------------------------------------------------------------- fixed4 NullPsClip (PS_INPUT IN) : SV_Target { float3 diff = abs(IN.clipPos - _GlobalClipCenter); if (diff.x > _GlobalClipExtents.x || diff.y > _GlobalClipExtents.y || diff.z > _GlobalClipExtents.z) discard; return float4(1.0, 0.0, 1.0, 1.0); }