Advertisement
Guest User

EdgeDetection.shader

a guest
Apr 19th, 2019
808
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1.  
  2. Shader "Hidden/EdgeDetect" {
  3.     Properties{
  4.         _MainTex("Base (RGB)", 2D) = "" {}
  5.     }
  6.  
  7.         CGINCLUDE
  8.  
  9. #include "UnityCG.cginc"
  10.  
  11.         struct v2f {
  12.         float4 pos : SV_POSITION;
  13.         float2 uv[5] : TEXCOORD0;
  14.     };
  15.  
  16.     struct v2fd {
  17.         float4 pos : SV_POSITION;
  18.         float2 uv[2] : TEXCOORD0;
  19.     };
  20.  
  21.     sampler2D _MainTex;
  22.     uniform float4 _MainTex_TexelSize;
  23.     half4 _MainTex_ST;
  24.  
  25.     sampler2D _CameraDepthNormalsTexture;
  26.     half4 _CameraDepthNormalsTexture_ST;
  27.  
  28.     sampler2D_float _CameraDepthTexture;
  29.     half4 _CameraDepthTexture_ST;
  30.  
  31.     uniform half4 _Sensitivity;
  32.     uniform half4 _BgColor;
  33.     uniform half _BgFade;
  34.     uniform half _SampleDistance;
  35.     uniform float _Exponent;
  36.  
  37.     uniform float _Threshold;
  38.  
  39.     struct v2flum {
  40.         float4 pos : SV_POSITION;
  41.         float2 uv[3] : TEXCOORD0;
  42.     };
  43.  
  44.     v2flum vertLum(appdata_img v)
  45.     {
  46.         v2flum o;
  47.         o.pos = UnityObjectToClipPos(v.vertex);
  48.         float2 uv = MultiplyUV(UNITY_MATRIX_TEXTURE0, v.texcoord);
  49.         o.uv[0] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
  50.         o.uv[1] = UnityStereoScreenSpaceUVAdjust(uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance, _MainTex_ST);
  51.         o.uv[2] = UnityStereoScreenSpaceUVAdjust(uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance, _MainTex_ST);
  52.         return o;
  53.     }
  54.  
  55.  
  56.     fixed4 fragLum(v2flum i) : SV_Target
  57.     {
  58.         fixed4 original = tex2D(_MainTex, i.uv[0]);
  59.  
  60.     // a very simple cross gradient filter
  61.  
  62.     half3 p1 = original.rgb;
  63.     half3 p2 = tex2D(_MainTex, i.uv[1]).rgb;
  64.     half3 p3 = tex2D(_MainTex, i.uv[2]).rgb;
  65.  
  66.     half3 diff = p1 * 2 - p2 - p3;
  67.     half len = dot(diff, diff);
  68.     len = step(len, _Threshold);
  69.     //if(len >= _Threshold)
  70.     //  original.rgb = 0;
  71.  
  72.     return len * lerp(original, _BgColor, _BgFade);
  73.     }
  74.  
  75.         inline half CheckSame(half2 centerNormal, float centerDepth, half4 theSample)
  76.     {
  77.         // difference in normals
  78.         // do not bother decoding normals - there's no need here
  79.         half2 diff = abs(centerNormal - theSample.xy) * _Sensitivity.y;
  80.         int isSameNormal = (diff.x + diff.y) * _Sensitivity.y < 0.1;
  81.         // difference in depth
  82.         float sampleDepth = DecodeFloatRG(theSample.zw);
  83.         float zdiff = abs(centerDepth - sampleDepth);
  84.         // scale the required threshold by the distance
  85.         int isSameDepth = zdiff * _Sensitivity.x < 0.09 * centerDepth;
  86.  
  87.         // return:
  88.         // 1 - if normals and depth are similar enough
  89.         // 0 - otherwise
  90.  
  91.         return isSameNormal * isSameDepth ? 1.0 : 0.0;
  92.     }
  93.  
  94.     v2f vertRobert(appdata_img v)
  95.     {
  96.         v2f o;
  97.         o.pos = UnityObjectToClipPos(v.vertex);
  98.  
  99.         float2 uv = v.texcoord.xy;
  100.         o.uv[0] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
  101.  
  102. #if UNITY_UV_STARTS_AT_TOP
  103.         if (_MainTex_TexelSize.y < 0)
  104.             uv.y = 1 - uv.y;
  105. #endif
  106.  
  107.         // calc coord for the X pattern
  108.         // maybe nicer TODO for the future: 'rotated triangles'
  109.  
  110.         o.uv[1] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(1, 1) * _SampleDistance, _MainTex_ST);
  111.         o.uv[2] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(-1, -1) * _SampleDistance, _MainTex_ST);
  112.         o.uv[3] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(-1, 1) * _SampleDistance, _MainTex_ST);
  113.         o.uv[4] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(1, -1) * _SampleDistance, _MainTex_ST);
  114.  
  115.         return o;
  116.     }
  117.  
  118.     v2f vertThin(appdata_img v)
  119.     {
  120.         v2f o;
  121.         o.pos = UnityObjectToClipPos(v.vertex);
  122.  
  123.         float2 uv = v.texcoord.xy;
  124.         o.uv[0] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
  125.  
  126. #if UNITY_UV_STARTS_AT_TOP
  127.         if (_MainTex_TexelSize.y < 0)
  128.             uv.y = 1 - uv.y;
  129. #endif
  130.  
  131.         o.uv[1] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
  132.         o.uv[4] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
  133.  
  134.         // offsets for two additional samples
  135.         o.uv[2] = UnityStereoScreenSpaceUVAdjust(uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance, _MainTex_ST);
  136.         o.uv[3] = UnityStereoScreenSpaceUVAdjust(uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance, _MainTex_ST);
  137.  
  138.         return o;
  139.     }
  140.  
  141.     v2fd vertD(appdata_img v)
  142.     {
  143.         v2fd o;
  144.         o.pos = UnityObjectToClipPos(v.vertex);
  145.  
  146.         float2 uv = v.texcoord.xy;
  147.         o.uv[0] = uv;
  148.  
  149. #if UNITY_UV_STARTS_AT_TOP
  150.         if (_MainTex_TexelSize.y < 0)
  151.             uv.y = 1 - uv.y;
  152. #endif
  153.  
  154.         o.uv[1] = uv;
  155.  
  156.         return o;
  157.     }
  158.  
  159.     float4 fragDCheap(v2fd i) : SV_Target
  160.     {
  161.         // inspired by borderlands implementation of popular "sobel filter"
  162.  
  163.         float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv[1]));
  164.         float4 depthsDiag;
  165.         float4 depthsAxis;
  166.  
  167.         float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;
  168.  
  169.         depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] + uvDist, _CameraDepthTexture_ST))); // TR
  170.         depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] + uvDist * float2(-1,1), _CameraDepthTexture_ST))); // TL
  171.         depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] - uvDist * float2(-1,1), _CameraDepthTexture_ST))); // BR
  172.         depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] - uvDist, _CameraDepthTexture_ST))); // BL
  173.  
  174.         depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] + uvDist * float2(0,1), _CameraDepthTexture_ST))); // T
  175.         depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] - uvDist * float2(1,0), _CameraDepthTexture_ST))); // L
  176.         depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] + uvDist * float2(1,0), _CameraDepthTexture_ST))); // R
  177.         depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] - uvDist * float2(0,1), _CameraDepthTexture_ST))); // B
  178.  
  179.         depthsDiag -= centerDepth;
  180.         depthsAxis /= centerDepth;
  181.  
  182.         const float4 HorizDiagCoeff = float4(1,1,-1,-1);
  183.         const float4 VertDiagCoeff = float4(-1,1,-1,1);
  184.         const float4 HorizAxisCoeff = float4(1,0,0,-1);
  185.         const float4 VertAxisCoeff = float4(0,1,-1,0);
  186.  
  187.         float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
  188.         float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;
  189.  
  190.         float SobelX = dot(SobelH, float4(1,1,1,1));
  191.         float SobelY = dot(SobelV, float4(1,1,1,1));
  192.         float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);
  193.  
  194.         Sobel = 1.0 - pow(saturate(Sobel), _Exponent);
  195.         return Sobel * lerp(tex2D(_MainTex, UnityStereoScreenSpaceUVAdjust(i.uv[0].xy, _MainTex_ST)), _BgColor, _BgFade);
  196.     }
  197.  
  198.         // pretty much also just a sobel filter, except for that edges "outside" the silhouette get discarded
  199.         //  which makes it compatible with other depth based post fx
  200.  
  201.         float4 fragD(v2fd i) : SV_Target
  202.     {
  203.         // inspired by borderlands implementation of popular "sobel filter"
  204.  
  205.         float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1], _CameraDepthTexture_ST)));
  206.         float4 depthsDiag;
  207.         float4 depthsAxis;
  208.  
  209.         float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;
  210.  
  211.         depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] + uvDist, _CameraDepthTexture_ST))); // TR
  212.         depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] + uvDist * float2(-1,1), _CameraDepthTexture_ST))); // TL
  213.         depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] - uvDist * float2(-1,1), _CameraDepthTexture_ST))); // BR
  214.         depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] - uvDist, _CameraDepthTexture_ST))); // BL
  215.  
  216.         depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] + uvDist * float2(0,1), _CameraDepthTexture_ST))); // T
  217.         depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] - uvDist * float2(1,0), _CameraDepthTexture_ST))); // L
  218.         depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] + uvDist * float2(1,0), _CameraDepthTexture_ST))); // R
  219.         depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1] - uvDist * float2(0,1), _CameraDepthTexture_ST))); // B
  220.  
  221.         // make it work nicely with depth based image effects such as depth of field:
  222.         depthsDiag = (depthsDiag > centerDepth.xxxx) ? depthsDiag : centerDepth.xxxx;
  223.         depthsAxis = (depthsAxis > centerDepth.xxxx) ? depthsAxis : centerDepth.xxxx;
  224.  
  225.         depthsDiag -= centerDepth;
  226.         depthsAxis /= centerDepth;
  227.  
  228.         const float4 HorizDiagCoeff = float4(1,1,-1,-1);
  229.         const float4 VertDiagCoeff = float4(-1,1,-1,1);
  230.         const float4 HorizAxisCoeff = float4(1,0,0,-1);
  231.         const float4 VertAxisCoeff = float4(0,1,-1,0);
  232.  
  233.         float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
  234.         float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;
  235.  
  236.         float SobelX = dot(SobelH, float4(1,1,1,1));
  237.         float SobelY = dot(SobelV, float4(1,1,1,1));
  238.         float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);
  239.  
  240.         Sobel = 1.0 - pow(saturate(Sobel), _Exponent);
  241.         return Sobel * lerp(tex2D(_MainTex, UnityStereoScreenSpaceUVAdjust(i.uv[0].xy, _MainTex_ST)), _BgColor, _BgFade);
  242.     }
  243.  
  244.         half4 fragRobert(v2f i) : SV_Target{
  245.             half4 sample1 = tex2D(_CameraDepthNormalsTexture, i.uv[1].xy);
  246.             half4 sample2 = tex2D(_CameraDepthNormalsTexture, i.uv[2].xy);
  247.             half4 sample3 = tex2D(_CameraDepthNormalsTexture, i.uv[3].xy);
  248.             half4 sample4 = tex2D(_CameraDepthNormalsTexture, i.uv[4].xy);
  249.  
  250.             half edge = 1.0;
  251.  
  252.             edge *= CheckSame(sample1.xy, DecodeFloatRG(sample1.zw), sample2);
  253.             edge *= CheckSame(sample3.xy, DecodeFloatRG(sample3.zw), sample4);
  254.  
  255.             return edge * lerp(tex2D(_MainTex, i.uv[0]), _BgColor, _BgFade);
  256.     }
  257.  
  258.         half4 fragThin(v2f i) : SV_Target
  259.     {
  260.         half4 original = tex2D(_MainTex, i.uv[0]);
  261.  
  262.         half4 center = tex2D(_CameraDepthNormalsTexture, i.uv[1]);
  263.         half4 sample1 = tex2D(_CameraDepthNormalsTexture, i.uv[2]);
  264.         half4 sample2 = tex2D(_CameraDepthNormalsTexture, i.uv[3]);
  265.  
  266.         // encoded normal
  267.         half2 centerNormal = center.xy;
  268.         // decoded depth
  269.         float centerDepth = DecodeFloatRG(center.zw);
  270.  
  271.         half edge = 1.0;
  272.  
  273.         edge *= CheckSame(centerNormal, centerDepth, sample1);
  274.         edge *= CheckSame(centerNormal, centerDepth, sample2);
  275.  
  276.         return edge * lerp(original, _BgColor, _BgFade);
  277.     }
  278.  
  279.         ENDCG
  280.  
  281.         Subshader {
  282.         Pass{
  283.              ZTest Always Cull Off ZWrite Off
  284.              Stencil{
  285.                Ref 1
  286.                Comp Equal
  287.                 Pass Keep
  288.            }
  289.              CGPROGRAM
  290.              #pragma vertex vertThin
  291.              #pragma fragment fragThin
  292.              ENDCG
  293.         }
  294.             Pass{
  295.  
  296.                  ZTest Always Cull Off ZWrite Off
  297.                  Stencil{
  298.                Ref 1
  299.                Comp Equal
  300.                 Pass Keep
  301.            }
  302.                  CGPROGRAM
  303.                  #pragma vertex vertRobert
  304.                  #pragma fragment fragRobert
  305.                  ENDCG
  306.         }
  307.             Pass{
  308.                  ZTest Always Cull Off ZWrite Off
  309.                  Stencil{
  310.                Ref 1
  311.                Comp Equal
  312.                 Pass Keep
  313.            }
  314.                  CGPROGRAM
  315.                  #pragma target 3.0  
  316.                  #pragma vertex vertD
  317.                  #pragma fragment fragDCheap
  318.                  ENDCG
  319.         }
  320.             Pass{
  321.                  ZTest Always Cull Off ZWrite Off
  322.                  Stencil{
  323.                Ref 1
  324.                Comp Equal
  325.                 Pass Keep
  326.            }
  327.                  CGPROGRAM
  328.                  #pragma target 3.0  
  329.                  #pragma vertex vertD
  330.                  #pragma fragment fragD
  331.                  ENDCG
  332.         }
  333.             Pass{
  334.                  ZTest Always Cull Off ZWrite Off
  335.                  Stencil{
  336.                Ref 1
  337.                Comp Equal
  338.                 Pass Keep
  339.            }
  340.                  CGPROGRAM
  341.                  #pragma target 3.0  
  342.                  #pragma vertex vertLum
  343.                  #pragma fragment fragLum
  344.                  ENDCG
  345.         }
  346.     }
  347.  
  348.     Fallback off
  349.  
  350. } // shader
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement