Wireframe.shader 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. // Copyright (c) Microsoft Corporation. All rights reserved.
  2. // Licensed under the MIT License. See LICENSE in the project root for license information.
  3. ///
  4. /// Basic wireframe shader that can be used for rendering spatial mapping meshes.
  5. ///
  6. Shader "ShadowSDK/Wireframe"
  7. {
  8. Properties
  9. {
  10. // Advanced options.
  11. [Enum(RenderingMode)] _Mode("Rendering Mode", Float) = 0 // "Opaque"
  12. [Enum(CustomRenderingMode)] _CustomMode("Mode", Float) = 0 // "Opaque"
  13. [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Source Blend", Float) = 1 // "One"
  14. [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Destination Blend", Float) = 0 // "Zero"
  15. [Enum(UnityEngine.Rendering.BlendOp)] _BlendOp("Blend Operation", Float) = 0 // "Add"
  16. [Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("Depth Test", Float) = 4 // "LessEqual"
  17. [Enum(DepthWrite)] _ZWrite("Depth Write", Float) = 1 // "On"
  18. _ZOffsetFactor("Depth Offset Factor", Float) = 0 // "Zero"
  19. _ZOffsetUnits("Depth Offset Units", Float) = 0 // "Zero"
  20. [Enum(UnityEngine.Rendering.ColorWriteMask)] _ColorWriteMask("Color Write Mask", Float) = 15 // "All"
  21. [Enum(UnityEngine.Rendering.CullMode)] _CullMode("Cull Mode", Float) = 2 // "Back"
  22. _RenderQueueOverride("Render Queue Override", Range(-1.0, 5000)) = -1
  23. _BaseColor("Base color", Color) = (0.0, 0.0, 0.0, 1.0)
  24. _WireColor("Wire color", Color) = (1.0, 1.0, 1.0, 1.0)
  25. _WireThickness("Wire thickness", Range(0, 800)) = 100
  26. }
  27. SubShader
  28. {
  29. Tags { "RenderType" = "Opaque" }
  30. Blend[_SrcBlend][_DstBlend]
  31. BlendOp[_BlendOp]
  32. ZTest[_ZTest]
  33. ZWrite[_ZWrite]
  34. Cull[_CullMode]
  35. Offset[_ZOffsetFactor],[_ZOffsetUnits]
  36. ColorMask[_ColorWriteMask]
  37. Pass
  38. {
  39. Offset 50, 100
  40. CGPROGRAM
  41. #pragma vertex vert
  42. #pragma geometry geom
  43. #pragma fragment frag
  44. #if defined(SHADER_API_D3D11)
  45. #pragma target 5.0
  46. #endif
  47. #include "UnityCG.cginc"
  48. float4 _BaseColor;
  49. float4 _WireColor;
  50. float _WireThickness;
  51. // Based on approach described in Shader-Based Wireframe Drawing (2008)
  52. // http://orbit.dtu.dk/en/publications/id(13e2122d-bec7-48de-beca-03ce6ea1c3f1).html
  53. struct v2g
  54. {
  55. float4 viewPos : SV_POSITION;
  56. UNITY_VERTEX_OUTPUT_STEREO
  57. };
  58. v2g vert(appdata_base v)
  59. {
  60. UNITY_SETUP_INSTANCE_ID(v);
  61. v2g o;
  62. o.viewPos = UnityObjectToClipPos(v.vertex);
  63. UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
  64. return o;
  65. }
  66. // inverseW is to counteract the effect of perspective-correct interpolation so that the lines
  67. // look the same thickness regardless of their depth in the scene.
  68. struct g2f
  69. {
  70. float4 viewPos : SV_POSITION;
  71. float inverseW : TEXCOORD0;
  72. float3 dist : TEXCOORD1;
  73. UNITY_VERTEX_OUTPUT_STEREO
  74. };
  75. [maxvertexcount(3)]
  76. void geom(triangle v2g i[3], inout TriangleStream<g2f> triStream)
  77. {
  78. // Calculate the vectors that define the triangle from the input points.
  79. float2 point0 = i[0].viewPos.xy / i[0].viewPos.w;
  80. float2 point1 = i[1].viewPos.xy / i[1].viewPos.w;
  81. float2 point2 = i[2].viewPos.xy / i[2].viewPos.w;
  82. // Calculate the area of the triangle.
  83. float2 vector0 = point2 - point1;
  84. float2 vector1 = point2 - point0;
  85. float2 vector2 = point1 - point0;
  86. float area = abs(vector1.x * vector2.y - vector1.y * vector2.x);
  87. float3 distScale[3];
  88. distScale[0] = float3(area / length(vector0), 0, 0);
  89. distScale[1] = float3(0, area / length(vector1), 0);
  90. distScale[2] = float3(0, 0, area / length(vector2));
  91. float wireScale = 800 - _WireThickness;
  92. // Output each original vertex with its distance to the opposing line defined
  93. // by the other two vertices.
  94. g2f o;
  95. [unroll]
  96. for (uint idx = 0; idx < 3; ++idx)
  97. {
  98. o.viewPos = i[idx].viewPos;
  99. o.inverseW = 1.0 / o.viewPos.w;
  100. o.dist = distScale[idx] * o.viewPos.w * wireScale;
  101. UNITY_TRANSFER_VERTEX_OUTPUT_STEREO(i[idx], o);
  102. triStream.Append(o);
  103. }
  104. }
  105. float4 frag(g2f i) : COLOR
  106. {
  107. // Calculate minimum distance to one of the triangle lines, making sure to correct
  108. // for perspective-correct interpolation.
  109. float dist = min(i.dist[0], min(i.dist[1], i.dist[2])) * i.inverseW;
  110. // Make the intensity of the line very bright along the triangle edges but fall-off very
  111. // quickly.
  112. float I = exp2(-2 * dist * dist);
  113. return I * _WireColor + (1 - I) * _BaseColor;
  114. }
  115. ENDCG
  116. }
  117. }
  118. FallBack "Diffuse"
  119. }