Assignment for RMIT Mixed Reality in 2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

182 lines
7.1 KiB

  1. //======= Copyright (c) Valve Corporation, All rights reserved. ===============
  2. //
  3. // Purpose: Used to show the outline of the object
  4. //
  5. //=============================================================================
  6. // UNITY_SHADER_NO_UPGRADE
  7. Shader "Valve/VR/Silhouette"
  8. {
  9. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  10. Properties
  11. {
  12. g_vOutlineColor( "Outline Color", Color ) = ( .5, .5, .5, 1 )
  13. g_flOutlineWidth( "Outline width", Range ( .001, 0.03 ) ) = .005
  14. g_flCornerAdjust( "Corner Adjustment", Range( 0, 2 ) ) = .5
  15. }
  16. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  17. CGINCLUDE
  18. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  19. #pragma target 5.0
  20. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  21. #include "UnityCG.cginc"
  22. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  23. float4 g_vOutlineColor;
  24. float g_flOutlineWidth;
  25. float g_flCornerAdjust;
  26. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  27. struct VS_INPUT
  28. {
  29. float4 vPositionOs : POSITION;
  30. float3 vNormalOs : NORMAL;
  31. };
  32. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  33. struct PS_INPUT
  34. {
  35. float4 vPositionOs : TEXCOORD0;
  36. float3 vNormalOs : TEXCOORD1;
  37. float4 vPositionPs : SV_POSITION;
  38. };
  39. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  40. PS_INPUT MainVs( VS_INPUT i )
  41. {
  42. PS_INPUT o;
  43. o.vPositionOs.xyzw = i.vPositionOs.xyzw;
  44. o.vNormalOs.xyz = i.vNormalOs.xyz;
  45. #if UNITY_VERSION >= 540
  46. o.vPositionPs = UnityObjectToClipPos( i.vPositionOs.xyzw );
  47. #else
  48. o.vPositionPs = mul( UNITY_MATRIX_MVP, i.vPositionOs.xyzw );
  49. #endif
  50. return o;
  51. }
  52. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  53. PS_INPUT Extrude( PS_INPUT vertex )
  54. {
  55. PS_INPUT extruded = vertex;
  56. // Offset along normal in projection space
  57. float3 vNormalVs = mul( ( float3x3 )UNITY_MATRIX_IT_MV, vertex.vNormalOs.xyz );
  58. float2 vOffsetPs = TransformViewToProjection( vNormalVs.xy );
  59. vOffsetPs.xy = normalize( vOffsetPs.xy );
  60. // Calculate position
  61. #if UNITY_VERSION >= 540
  62. extruded.vPositionPs = UnityObjectToClipPos( vertex.vPositionOs.xyzw );
  63. #else
  64. extruded.vPositionPs = mul( UNITY_MATRIX_MVP, vertex.vPositionOs.xyzw );
  65. #endif
  66. extruded.vPositionPs.xy += vOffsetPs.xy * extruded.vPositionPs.w * g_flOutlineWidth;
  67. return extruded;
  68. }
  69. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  70. [maxvertexcount(18)]
  71. void ExtrudeGs( triangle PS_INPUT inputTriangle[3], inout TriangleStream<PS_INPUT> outputStream )
  72. {
  73. float3 a = normalize(inputTriangle[0].vPositionOs.xyz - inputTriangle[1].vPositionOs.xyz);
  74. float3 b = normalize(inputTriangle[1].vPositionOs.xyz - inputTriangle[2].vPositionOs.xyz);
  75. float3 c = normalize(inputTriangle[2].vPositionOs.xyz - inputTriangle[0].vPositionOs.xyz);
  76. inputTriangle[0].vNormalOs = inputTriangle[0].vNormalOs + normalize( a - c) * g_flCornerAdjust;
  77. inputTriangle[1].vNormalOs = inputTriangle[1].vNormalOs + normalize(-a + b) * g_flCornerAdjust;
  78. inputTriangle[2].vNormalOs = inputTriangle[2].vNormalOs + normalize(-b + c) * g_flCornerAdjust;
  79. PS_INPUT extrudedTriangle0 = Extrude( inputTriangle[0] );
  80. PS_INPUT extrudedTriangle1 = Extrude( inputTriangle[1] );
  81. PS_INPUT extrudedTriangle2 = Extrude( inputTriangle[2] );
  82. outputStream.Append( inputTriangle[0] );
  83. outputStream.Append( extrudedTriangle0 );
  84. outputStream.Append( inputTriangle[1] );
  85. outputStream.Append( extrudedTriangle0 );
  86. outputStream.Append( extrudedTriangle1 );
  87. outputStream.Append( inputTriangle[1] );
  88. outputStream.Append( inputTriangle[1] );
  89. outputStream.Append( extrudedTriangle1 );
  90. outputStream.Append( extrudedTriangle2 );
  91. outputStream.Append( inputTriangle[1] );
  92. outputStream.Append( extrudedTriangle2 );
  93. outputStream.Append( inputTriangle[2] );
  94. outputStream.Append( inputTriangle[2] );
  95. outputStream.Append( extrudedTriangle2 );
  96. outputStream.Append(inputTriangle[0]);
  97. outputStream.Append( extrudedTriangle2 );
  98. outputStream.Append( extrudedTriangle0 );
  99. outputStream.Append( inputTriangle[0] );
  100. }
  101. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  102. fixed4 MainPs( PS_INPUT i ) : SV_Target
  103. {
  104. return g_vOutlineColor;
  105. }
  106. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  107. fixed4 NullPs( PS_INPUT i ) : SV_Target
  108. {
  109. return float4( 1.0, 0.0, 1.0, 1.0 );
  110. }
  111. ENDCG
  112. SubShader
  113. {
  114. Tags { "RenderType"="Outline" "Queue" = "Geometry-1" }
  115. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  116. // Render the object with stencil=1 to mask out the part that isn't the silhouette
  117. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  118. Pass
  119. {
  120. Tags { "LightMode" = "Always" }
  121. ColorMask 0
  122. Cull Off
  123. ZWrite Off
  124. Stencil
  125. {
  126. Ref 1
  127. Comp always
  128. Pass replace
  129. }
  130. CGPROGRAM
  131. #pragma vertex MainVs
  132. #pragma fragment NullPs
  133. ENDCG
  134. }
  135. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  136. // Render the outline by extruding along vertex normals and using the stencil mask previously rendered. Only render depth, so that the final pass executes
  137. // once per fragment (otherwise alpha blending will look bad).
  138. //-------------------------------------------------------------------------------------------------------------------------------------------------------------
  139. Pass
  140. {
  141. Tags { "LightMode" = "Always" }
  142. Cull Off
  143. ZWrite On
  144. Stencil
  145. {
  146. Ref 1
  147. Comp notequal
  148. Pass keep
  149. Fail keep
  150. }
  151. CGPROGRAM
  152. #pragma vertex MainVs
  153. #pragma geometry ExtrudeGs
  154. #pragma fragment MainPs
  155. ENDCG
  156. }
  157. }
  158. }