EdgeDetectNormals.shader 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. // Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
  2. Shader "Hidden/EdgeDetectGeometry" {
  3. Properties {
  4. _MainTex ("Base (RGB)", 2D) = "" {}
  5. }
  6. // Shader code pasted into all further CGPROGRAM blocks
  7. CGINCLUDE
  8. #include "UnityCG.cginc"
  9. struct v2f {
  10. float4 pos : POSITION;
  11. float2 uv[5] : TEXCOORD0;
  12. };
  13. sampler2D _MainTex;
  14. uniform half4 _MainTex_TexelSize;
  15. sampler2D _CameraDepthNormalsTexture;
  16. uniform half4 sensitivity;
  17. uniform half4 _BgColor;
  18. uniform half _BgFade;
  19. inline half CheckSame (half2 centerNormal, float centerDepth, half4 sample)
  20. {
  21. // difference in normals
  22. // do not bother decoding normals - there's no need here
  23. half2 diff = abs(centerNormal - sample.xy) * sensitivity.y;
  24. half isSameNormal = (diff.x + diff.y) * sensitivity.y < 0.1;
  25. // difference in depth
  26. float sampleDepth = DecodeFloatRG (sample.zw);
  27. float zdiff = abs(centerDepth-sampleDepth);
  28. // scale the required threshold by the distance
  29. half isSameDepth = zdiff * sensitivity.x < 0.09 * centerDepth;
  30. // return:
  31. // 1 - if normals and depth are similar enough
  32. // 0 - otherwise
  33. return isSameNormal * isSameDepth;
  34. }
  35. v2f vertRobert( appdata_img v )
  36. {
  37. v2f o;
  38. o.pos = UnityObjectToClipPos(v.vertex);
  39. float2 uv = v.texcoord.xy;
  40. o.uv[0] = uv;
  41. // On D3D when AA is used, the main texture & scene depth texture
  42. // will come out in different vertical orientations.
  43. // So flip sampling of depth texture when that is the case (main texture
  44. // texel size will have negative Y)
  45. #if SHADER_API_D3D9
  46. if (_MainTex_TexelSize.y < 0)
  47. uv.y = 1-uv.y;
  48. #endif
  49. // calc coord for the X pattern
  50. // maybe nicer TODO for the future: rotated triangles
  51. o.uv[0] = uv;
  52. o.uv[1] = uv + _MainTex_TexelSize.xy * half2(1,1);
  53. o.uv[2] = uv + _MainTex_TexelSize.xy * half2(-1,-1);
  54. o.uv[3] = uv + _MainTex_TexelSize.xy * half2(-1,1);
  55. o.uv[4] = uv + _MainTex_TexelSize.xy * half2(1,-1);
  56. return o;
  57. }
  58. v2f vertThin( appdata_img v )
  59. {
  60. v2f o;
  61. o.pos = UnityObjectToClipPos (v.vertex);
  62. float2 uv = v.texcoord.xy;
  63. o.uv[0] = uv;
  64. // On D3D when AA is used, the main texture & scene depth texture
  65. // will come out in different vertical orientations.
  66. // So flip sampling of depth texture when that is the case (main texture
  67. // texel size will have negative Y)
  68. #if SHADER_API_D3D9
  69. if (_MainTex_TexelSize.y < 0)
  70. uv.y = 1-uv.y;
  71. #endif
  72. o.uv[1] = uv;
  73. o.uv[4] = uv;
  74. // offsets for two additional samples
  75. o.uv[2] = uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y);
  76. o.uv[3] = uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y);
  77. return o;
  78. }
  79. half4 fragRobert(v2f i) : COLOR {
  80. //half4 sample0 = tex2D(_CameraDepthNormalsTexture, i.uv[0].xy);
  81. half4 sample1 = tex2D(_CameraDepthNormalsTexture, i.uv[1].xy);
  82. half4 sample2 = tex2D(_CameraDepthNormalsTexture, i.uv[2].xy);
  83. half4 sample3 = tex2D(_CameraDepthNormalsTexture, i.uv[3].xy);
  84. half4 sample4 = tex2D(_CameraDepthNormalsTexture, i.uv[4].xy);
  85. half edge = 1.0;
  86. edge *= CheckSame(sample1.xy, DecodeFloatRG(sample1.zw), sample2);
  87. edge *= CheckSame(sample3.xy, DecodeFloatRG(sample3.zw), sample4);
  88. return edge * lerp(tex2D(_MainTex, i.uv[0].xy), _BgColor, _BgFade);
  89. }
  90. half4 fragThin (v2f i) : COLOR
  91. {
  92. half4 original = tex2D(_MainTex, i.uv[0]);
  93. half4 center = tex2D (_CameraDepthNormalsTexture, i.uv[1]);
  94. half4 sample1 = tex2D (_CameraDepthNormalsTexture, i.uv[2]);
  95. half4 sample2 = tex2D (_CameraDepthNormalsTexture, i.uv[3]);
  96. // encoded normal
  97. half2 centerNormal = center.xy;
  98. // decoded depth
  99. float centerDepth = DecodeFloatRG (center.zw);
  100. half edge = 1.0;
  101. edge *= CheckSame(centerNormal, centerDepth, sample1);
  102. edge *= CheckSame(centerNormal, centerDepth, sample2);
  103. return edge * lerp(original, _BgColor, _BgFade);
  104. }
  105. ENDCG
  106. Subshader {
  107. Pass {
  108. ZTest Always Cull Off ZWrite Off
  109. Fog { Mode off }
  110. CGPROGRAM
  111. #pragma vertex vertThin
  112. #pragma fragment fragThin
  113. ENDCG
  114. }
  115. Pass {
  116. ZTest Always Cull Off ZWrite Off
  117. Fog { Mode off }
  118. CGPROGRAM
  119. #pragma vertex vertRobert
  120. #pragma fragment fragRobert
  121. ENDCG
  122. }
  123. }
  124. Fallback off
  125. } // shader