123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319 |
- //======= Copyright (c) Valve Corporation, All rights reserved. ===============
- //
- // Purpose: Used to show the outline of the object
- //
- //=============================================================================
- // UNITY_SHADER_NO_UPGRADE
- Shader "Valve/VR/Silhouette"
- {
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- Properties
- {
- g_vOutlineColor( "Outline Color", Color ) = ( .5, .5, .5, 1 )
- g_flOutlineWidth( "Outline width", Range ( .001, 0.03 ) ) = .005
- g_flCornerAdjust( "Corner Adjustment", Range( 0, 2 ) ) = .5
- }
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- CGINCLUDE
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- #pragma target 5.0
- #pragma multi_compile_instancing
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- #include "UnityCG.cginc"
- #if UNITY_VERSION >= 201810
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- UNITY_INSTANCING_BUFFER_START( Props )
- UNITY_DEFINE_INSTANCED_PROP( float4, g_vOutlineColor )
- UNITY_DEFINE_INSTANCED_PROP( float, g_flOutlineWidth )
- UNITY_DEFINE_INSTANCED_PROP( float, g_flCornerAdjust )
- UNITY_INSTANCING_BUFFER_END( Props )
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- struct VS_INPUT
- {
- float4 vPositionOs : POSITION;
- float3 vNormalOs : NORMAL;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- };
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- struct PS_INPUT
- {
- float4 vPositionOs : TEXCOORD0;
- float3 vNormalOs : TEXCOORD1;
- float4 vPositionPs : SV_POSITION;
- UNITY_VERTEX_INPUT_INSTANCE_ID
- UNITY_VERTEX_OUTPUT_STEREO
- };
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- PS_INPUT MainVs( VS_INPUT i )
- {
- PS_INPUT o;
- UNITY_SETUP_INSTANCE_ID( i );
- UNITY_INITIALIZE_OUTPUT( PS_INPUT, o );
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( o );
- o.vPositionOs.xyzw = i.vPositionOs.xyzw;
- o.vNormalOs.xyz = i.vNormalOs.xyz;
- o.vPositionPs = UnityObjectToClipPos( i.vPositionOs.xyzw );
- 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
- extruded.vPositionPs = UnityObjectToClipPos( vertex.vPositionOs.xyzw );
- extruded.vPositionPs.xy += vOffsetPs.xy * extruded.vPositionPs.w * UNITY_ACCESS_INSTANCED_PROP( Props, g_flOutlineWidth );
- return extruded;
- }
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- [maxvertexcount(18)]
- void ExtrudeGs( triangle PS_INPUT inputTriangle[3], inout TriangleStream<PS_INPUT> outputStream )
- {
- UNITY_SETUP_INSTANCE_ID ( inputTriangle[ 0 ] )
- UNITY_SETUP_INSTANCE_ID ( inputTriangle[ 1 ] )
- UNITY_SETUP_INSTANCE_ID ( inputTriangle[ 2 ] )
- DEFAULT_UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX ( inputTriangle[ 0 ] )
- DEFAULT_UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX ( inputTriangle[ 1 ] )
- DEFAULT_UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX ( inputTriangle[ 2 ] )
- PS_INPUT inputTriangle0 = inputTriangle[ 0 ];
- PS_INPUT inputTriangle1 = inputTriangle[ 1 ];
- PS_INPUT inputTriangle2 = inputTriangle[ 2 ];
- float3 a = normalize(inputTriangle0.vPositionOs.xyz - inputTriangle1.vPositionOs.xyz);
- float3 b = normalize(inputTriangle1.vPositionOs.xyz - inputTriangle2.vPositionOs.xyz);
- float3 c = normalize(inputTriangle2.vPositionOs.xyz - inputTriangle0.vPositionOs.xyz);
- inputTriangle0.vNormalOs = inputTriangle0.vNormalOs + normalize( a - c) * UNITY_ACCESS_INSTANCED_PROP( Props, g_flCornerAdjust );
- inputTriangle1.vNormalOs = inputTriangle1.vNormalOs + normalize(-a + b) * UNITY_ACCESS_INSTANCED_PROP( Props, g_flCornerAdjust );
- inputTriangle2.vNormalOs = inputTriangle2.vNormalOs + normalize(-b + c) * UNITY_ACCESS_INSTANCED_PROP( Props, g_flCornerAdjust );
- PS_INPUT extrudedTriangle0;
- PS_INPUT extrudedTriangle1;
- PS_INPUT extrudedTriangle2;
- UNITY_INITIALIZE_OUTPUT( PS_INPUT, extrudedTriangle0 );
- UNITY_INITIALIZE_OUTPUT( PS_INPUT, extrudedTriangle0 );
- UNITY_INITIALIZE_OUTPUT( PS_INPUT, extrudedTriangle0 );
-
- extrudedTriangle0 = Extrude( inputTriangle0 );
- extrudedTriangle1 = Extrude( inputTriangle1 );
- extrudedTriangle2 = Extrude( inputTriangle2 );
- outputStream.Append( inputTriangle0 );
- outputStream.Append( extrudedTriangle0 );
- outputStream.Append( inputTriangle1 );
- outputStream.Append( extrudedTriangle0 );
- outputStream.Append( extrudedTriangle1 );
- outputStream.Append( inputTriangle1 );
- outputStream.Append( inputTriangle1 );
- outputStream.Append( extrudedTriangle1 );
- outputStream.Append( extrudedTriangle2 );
- outputStream.Append( inputTriangle1 );
- outputStream.Append( extrudedTriangle2 );
- outputStream.Append( inputTriangle2 );
- outputStream.Append( inputTriangle2 );
- outputStream.Append( extrudedTriangle2 );
- outputStream.Append( inputTriangle0 );
- outputStream.Append( extrudedTriangle2 );
- outputStream.Append( extrudedTriangle0 );
- outputStream.Append( inputTriangle0 );
- }
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- fixed4 MainPs( PS_INPUT i ) : SV_Target
- {
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( i );
- return UNITY_ACCESS_INSTANCED_PROP( Props, g_vOutlineColor );
- }
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- fixed4 NullPs( PS_INPUT i ) : SV_Target
- {
- UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO( i );
- return float4( 1.0, 0.0, 1.0, 1.0 );
- }
- #else
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- float4 g_vOutlineColor;
- float g_flOutlineWidth;
- float g_flCornerAdjust;
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- struct VS_INPUT
- {
- float4 vPositionOs : POSITION;
- float3 vNormalOs : NORMAL;
- };
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- struct PS_INPUT
- {
- float4 vPositionOs : TEXCOORD0;
- float3 vNormalOs : TEXCOORD1;
- 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 = mul( UNITY_MATRIX_MVP, i.vPositionOs.xyzw );
- #endif
- 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 = mul( UNITY_MATRIX_MVP, 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<PS_INPUT> 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 i ) : SV_Target
- {
- return g_vOutlineColor;
- }
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- fixed4 NullPs( PS_INPUT i ) : SV_Target
- {
- return float4( 1.0, 0.0, 1.0, 1.0 );
- }
- #endif
- ENDCG
- SubShader
- {
- Tags { "RenderType"="Outline" "Queue" = "Geometry-1" }
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- // Render the object with stencil=1 to mask out the part that isn't the silhouette
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- Pass
- {
- Tags { "LightMode" = "Always" }
- ColorMask 0
- Cull Off
- ZWrite Off
- Stencil
- {
- Ref 1
- Comp always
- Pass replace
- }
- CGPROGRAM
- #pragma vertex MainVs
- #pragma fragment NullPs
- ENDCG
- }
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- // Render the outline by extruding along vertex normals and using the stencil mask previously rendered. Only render depth, so that the final pass executes
- // once per fragment (otherwise alpha blending will look bad).
- //-------------------------------------------------------------------------------------------------------------------------------------------------------------
- Pass
- {
- Tags { "LightMode" = "Always" }
- Cull Off
- ZWrite On
- Stencil
- {
- Ref 1
- Comp notequal
- Pass keep
- Fail keep
- }
- CGPROGRAM
- #pragma vertex MainVs
- #pragma geometry ExtrudeGs
- #pragma fragment MainPs
- ENDCG
- }
- }
- }
|