• Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
  • Help Room /
avatar image
Question by Vusa360 · Jan 31, 2018 at 08:19 PM · c#shaderrendertextureedge detection

Selectively apply material via RaycastHit

I am trying to modify the old Unity script Edge Detection to apply an outline to the edges of shapes based on whether or not they are being looked at.

So far I have changed EdgeDetection.cs to the code below. This is the script that is attached to the main camera in the scene and it currently doesn't render any overlay unless certain objects are being looked at. My problem is it currently detects edges on every object in the scene when a single object in collectionsToShow is hovered over. Is there any way to restrict this edge detection to only the current collection being hovered over?


EdgeDetection.cs

 using System;
 using UnityEngine;

 namespace UnityStandardAssets.ImageEffects
 {
     [ExecuteInEditMode]
     [RequireComponent (typeof (Camera))]
     [AddComponentMenu ("Image Effects/Edge Detection/Edge Detection")]
     public class EdgeDetection : PostEffectsBase
     {
         public enum EdgeDetectMode
         {
             TriangleDepthNormals = 0,
             RobertsCrossDepthNormals = 1,
             SobelDepth = 2,
             SobelDepthThin = 3,
             TriangleLuminance = 4,
         }

         public GameObject[] collectionsToShow;
         public EdgeDetectMode mode = EdgeDetectMode.SobelDepthThin;
         public float sensitivityDepth = 1.0f;
         public float sensitivityNormals = 1.0f;
         public float lumThreshold = 0.2f;
         public float edgeExp = 1.0f;
         public float sampleDist = 1.0f;
         [Range(0, 1)]
         public float edgesOnly = 0.0f;
         public Color edgesOnlyBgColor = Color.white;

         public Shader edgeDetectShader;
         private Material edgeDetectMaterial = null;
         private EdgeDetectMode oldMode = EdgeDetectMode.SobelDepthThin;
         private int? hitObject;
     
         public override bool CheckResources()
         {
             CheckSupport (true);

             edgeDetectMaterial = CheckShaderAndCreateMaterial(edgeDetectShader, edgeDetectMaterial);
             if (mode != oldMode)
                 SetCameraFlag ();

             oldMode = mode;

             if (!isSupported)
                 ReportAutoDisable ();
             return isSupported;
         }


         new void Start ()
         {
             oldMode    = mode;
         }

         void SetCameraFlag ()
         {
             if (mode == EdgeDetectMode.SobelDepth || mode == EdgeDetectMode.SobelDepthThin)
                 GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;
             else if (mode == EdgeDetectMode.TriangleDepthNormals || mode == EdgeDetectMode.RobertsCrossDepthNormals)
                 GetComponent<Camera>().depthTextureMode |= DepthTextureMode.DepthNormals;
         }

         void OnEnable ()
         {
             SetCameraFlag();
         }

         private void LateUpdate()
         {
             hitObject = null;
             Ray ray = new Ray(transform.position, transform.forward);
             RaycastHit hit;
             if (Physics.Raycast(ray, out hit, 10))
             {
                 for (int i = 0; i < collectionsToShow.Length; i++)
                 {
                     if (collectionsToShow[i].transform.childCount == 0)
                     {
                         if (hit.collider == collectionsToShow[i].GetComponent<Collider>())
                         {
                             hitObject = i;
                         }
                     }
                     else
                     {
                         Component[] colliders;
                         colliders = collectionsToShow[i].GetComponentsInChildren(typeof(Collider));

                         foreach (Collider col in colliders)
                         {
                             if (hit.collider == col)
                             {
                                 hitObject = i;
                             }
                         }
                     }
                 }
             }

             if(hitObject != null)
             {
                 //Should it be handled here?
             }
         }

         [ImageEffectOpaque]
         void OnRenderImage (RenderTexture source, RenderTexture destination)
         {
             if(hitObject != null) {
                 if (CheckResources() == false)
                 {
                     Graphics.Blit(source, destination);
                     return;
                 }

                 Vector2 sensitivity = new Vector2(sensitivityDepth, sensitivityNormals);
                 edgeDetectMaterial.SetVector("_Sensitivity", new Vector4(sensitivity.x, sensitivity.y, 1.0f, sensitivity.y));
                 edgeDetectMaterial.SetFloat("_BgFade", edgesOnly);
                 edgeDetectMaterial.SetFloat("_SampleDistance", sampleDist);
                 edgeDetectMaterial.SetVector("_BgColor", edgesOnlyBgColor);
                 edgeDetectMaterial.SetFloat("_Exponent", edgeExp);
                 edgeDetectMaterial.SetFloat("_Threshold", lumThreshold);

                 Graphics.Blit(source, destination, edgeDetectMaterial, (int)mode);
             } else
             {
                 Graphics.Blit(source, destination);
             }
         }
     }
 }


Unchanged, but required, code from Legacy Image Effects

PostEffectsBase.cs

 using System;
 using System.Collections.Generic;
 using UnityEngine;

 namespace UnityStandardAssets.ImageEffects
 {
     [ExecuteInEditMode]
     [RequireComponent (typeof(Camera))]
     public class PostEffectsBase : MonoBehaviour
     {
         protected bool  supportHDRTextures = true;
         protected bool  supportDX11 = false;
         protected bool  isSupported = true;

         private List<Material> createdMaterials = new List<Material> ();

         protected Material CheckShaderAndCreateMaterial ( Shader s, Material m2Create)
         {
             if (!s)
             {
                 Debug.Log("Missing shader in " + ToString ());
                 enabled = false;
                 return null;
             }

             if (s.isSupported && m2Create && m2Create.shader == s)
                 return m2Create;

             if (!s.isSupported)
             {
                 NotSupported ();
                 Debug.Log("The shader " + s.ToString() + " on effect "+ToString()+" is not supported on this platform!");
                 return null;
             }

             m2Create = new Material (s);
             createdMaterials.Add (m2Create);
             m2Create.hideFlags = HideFlags.DontSave;

             return m2Create;
         }


         protected Material CreateMaterial (Shader s, Material m2Create)
         {
             if (!s)
             {
                 Debug.Log ("Missing shader in " + ToString ());
                 return null;
             }

             if (m2Create && (m2Create.shader == s) && (s.isSupported))
                 return m2Create;

             if (!s.isSupported)
             {
                 return null;
             }

             m2Create = new Material (s);
             createdMaterials.Add (m2Create);
             m2Create.hideFlags = HideFlags.DontSave;
             
             return m2Create;
         }

         void OnEnable ()
         {
             isSupported = true;
         }

         void OnDestroy ()
         {
             RemoveCreatedMaterials ();    
         }

         private void RemoveCreatedMaterials ()
         {
             while (createdMaterials.Count > 0)
             {
                 Material mat = createdMaterials[0];
                 createdMaterials.RemoveAt (0);
 #if UNITY_EDITOR
                 DestroyImmediate (mat);
 #else
                 Destroy(mat);
 #endif
             }
         }

         protected bool CheckSupport ()
         {
             return CheckSupport (false);
         }


         public virtual bool CheckResources ()
         {
             Debug.LogWarning ("CheckResources () for " + ToString() + " should be overwritten.");
             return isSupported;
         }


         protected void Start ()
         {
             CheckResources ();
         }

         protected bool CheckSupport (bool needDepth)
         {
             isSupported = true;
             supportHDRTextures = SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.ARGBHalf);
             supportDX11 = SystemInfo.graphicsShaderLevel >= 50 && SystemInfo.supportsComputeShaders;

             if (!SystemInfo.supportsImageEffects)
             {
                 NotSupported ();
                 return false;
             }

             if (needDepth && !SystemInfo.SupportsRenderTextureFormat (RenderTextureFormat.Depth))
             {
                 NotSupported ();
                 return false;
             }

             if (needDepth)
                 GetComponent<Camera>().depthTextureMode |= DepthTextureMode.Depth;

             return true;
         }

         protected bool CheckSupport (bool needDepth,  bool needHdr)
         {
             if (!CheckSupport(needDepth))
                 return false;

             if (needHdr && !supportHDRTextures)
             {
                 NotSupported ();
                 return false;
             }

             return true;
         }


         public bool Dx11Support ()
         {
             return supportDX11;
         }


         protected void ReportAutoDisable ()
         {
             Debug.LogWarning ("The image effect " + ToString() + " has been disabled as it's not supported on the current platform.");
         }

         // deprecated but needed for old effects to survive upgrading
         bool CheckShader (Shader s)
         {
             Debug.Log("The shader " + s.ToString () + " on effect "+ ToString () + " is not part of the Unity 3.2+ effects suite anymore. For best performance and quality, please ensure you are using the latest Standard Assets Image Effects (Pro only) package.");
             if (!s.isSupported)
             {
                 NotSupported ();
                 return false;
             }
             else
             {
                 return false;
             }
         }


         protected void NotSupported ()
         {
             enabled = false;
             isSupported = false;
             return;
         }


         protected void DrawBorder (RenderTexture dest, Material material)
         {
             float x1;
             float x2;
             float y1;
             float y2;

             RenderTexture.active = dest;
             bool  invertY = true; // source.texelSize.y < 0.0ff;
             // Set up the simple Matrix
             GL.PushMatrix();
             GL.LoadOrtho();

             for (int i = 0; i < material.passCount; i++)
             {
                 material.SetPass(i);

                 float y1_; float y2_;
                 if (invertY)
                 {
                     y1_ = 1.0f; y2_ = 0.0f;
                 }
                 else
                 {
                     y1_ = 0.0f; y2_ = 1.0f;
                 }

                 // left
                 x1 = 0.0f;
                 x2 = 0.0f + 1.0f/(dest.width*1.0f);
                 y1 = 0.0f;
                 y2 = 1.0f;
                 GL.Begin(GL.QUADS);

                 GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
                 GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
                 GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
                 GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);

                 // right
                 x1 = 1.0f - 1.0f/(dest.width*1.0f);
                 x2 = 1.0f;
                 y1 = 0.0f;
                 y2 = 1.0f;

                 GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
                 GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
                 GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
                 GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);

                 // top
                 x1 = 0.0f;
                 x2 = 1.0f;
                 y1 = 0.0f;
                 y2 = 0.0f + 1.0f/(dest.height*1.0f);

                 GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
                 GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
                 GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
                 GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);

                 // bottom
                 x1 = 0.0f;
                 x2 = 1.0f;
                 y1 = 1.0f - 1.0f/(dest.height*1.0f);
                 y2 = 1.0f;

                 GL.TexCoord2(0.0f, y1_); GL.Vertex3(x1, y1, 0.1f);
                 GL.TexCoord2(1.0f, y1_); GL.Vertex3(x2, y1, 0.1f);
                 GL.TexCoord2(1.0f, y2_); GL.Vertex3(x2, y2, 0.1f);
                 GL.TexCoord2(0.0f, y2_); GL.Vertex3(x1, y2, 0.1f);

                 GL.End();
             }

             GL.PopMatrix();
         }
     }
 }

EdgeDetectNormals.shader

 Shader "Hidden/EdgeDetect" { 
     Properties {
         _MainTex ("Base (RGB)", 2D) = "" {}
     }

     CGINCLUDE
 
     #include "UnityCG.cginc"
 
     struct v2f {
         float4 pos : SV_POSITION;
         float2 uv[5] : TEXCOORD0;
     };
 
     struct v2fd {
         float4 pos : SV_POSITION;
         float2 uv[2] : TEXCOORD0;
     };

     sampler2D _MainTex;
     uniform float4 _MainTex_TexelSize;
     half4 _MainTex_ST;

     sampler2D _CameraDepthNormalsTexture;
     half4 _CameraDepthNormalsTexture_ST;

     sampler2D_float _CameraDepthTexture;
     half4 _CameraDepthTexture_ST;

     uniform half4 _Sensitivity; 
     uniform half4 _BgColor;
     uniform half _BgFade;
     uniform half _SampleDistance;
     uniform float _Exponent;

     uniform float _Threshold;

     struct v2flum {
         float4 pos : SV_POSITION;
         float2 uv[3] : TEXCOORD0;
     };

     v2flum vertLum (appdata_img v)
     {
         v2flum o;
         o.pos = UnityObjectToClipPos(v.vertex);
         float2 uv = MultiplyUV( UNITY_MATRIX_TEXTURE0, v.texcoord );
         o.uv[0] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
         o.uv[1] = UnityStereoScreenSpaceUVAdjust(uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance, _MainTex_ST);
         o.uv[2] = UnityStereoScreenSpaceUVAdjust(uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance, _MainTex_ST);
         return o;
     }


     fixed4 fragLum (v2flum i) : SV_Target
     {
         fixed4 original = tex2D(_MainTex, i.uv[0]);

         // a very simple cross gradient filter

         half3 p1 = original.rgb;
         half3 p2 = tex2D(_MainTex, i.uv[1]).rgb;
         half3 p3 = tex2D(_MainTex, i.uv[2]).rgb;
     
         half3 diff = p1 * 2 - p2 - p3;
         half len = dot(diff, diff);
         len = step(len, _Threshold);
         //if(len >= _Threshold)
         //    original.rgb = 0;

         return len * lerp(original, _BgColor, _BgFade);            
     }    
 
     inline half CheckSame (half2 centerNormal, float centerDepth, half4 theSample)
     {
         // difference in normals
         // do not bother decoding normals - there's no need here
         half2 diff = abs(centerNormal - theSample.xy) * _Sensitivity.y;
         int isSameNormal = (diff.x + diff.y) * _Sensitivity.y < 0.1;
         // difference in depth
         float sampleDepth = DecodeFloatRG (theSample.zw);
         float zdiff = abs(centerDepth-sampleDepth);
         // scale the required threshold by the distance
         int isSameDepth = zdiff * _Sensitivity.x < 0.09 * centerDepth;
 
         // return:
         // 1 - if normals and depth are similar enough
         // 0 - otherwise
     
         return isSameNormal * isSameDepth ? 1.0 : 0.0;
     }    
     
     v2f vertRobert( appdata_img v ) 
     {
         v2f o;
         o.pos = UnityObjectToClipPos(v.vertex);
     
         float2 uv = v.texcoord.xy;
         o.uv[0] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
     
         #if UNITY_UV_STARTS_AT_TOP
         if (_MainTex_TexelSize.y < 0)
             uv.y = 1-uv.y;
         #endif
             
         // calc coord for the X pattern
         // maybe nicer TODO for the future: 'rotated triangles'
     
         o.uv[1] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(1,1) * _SampleDistance, _MainTex_ST);
         o.uv[2] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(-1,-1) * _SampleDistance, _MainTex_ST);
         o.uv[3] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(-1,1) * _SampleDistance, _MainTex_ST);
         o.uv[4] = UnityStereoScreenSpaceUVAdjust(uv + _MainTex_TexelSize.xy * half2(1,-1) * _SampleDistance, _MainTex_ST);
              
         return o;
     } 
 
     v2f vertThin( appdata_img v )
     {
         v2f o;
         o.pos = UnityObjectToClipPos(v.vertex);
     
         float2 uv = v.texcoord.xy;
         o.uv[0] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
     
         #if UNITY_UV_STARTS_AT_TOP
         if (_MainTex_TexelSize.y < 0)
             uv.y = 1-uv.y;
         #endif
     
         o.uv[1] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
         o.uv[4] = UnityStereoScreenSpaceUVAdjust(uv, _MainTex_ST);
             
         // offsets for two additional samples
         o.uv[2] = UnityStereoScreenSpaceUVAdjust(uv + float2(-_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance, _MainTex_ST);
         o.uv[3] = UnityStereoScreenSpaceUVAdjust(uv + float2(+_MainTex_TexelSize.x, -_MainTex_TexelSize.y) * _SampleDistance, _MainTex_ST);
     
         return o;
     }      
  
     v2fd vertD( appdata_img v )
     {
         v2fd o;
         o.pos = UnityObjectToClipPos(v.vertex);
     
         float2 uv = v.texcoord.xy;
         o.uv[0] = uv;
     
         #if UNITY_UV_STARTS_AT_TOP
         if (_MainTex_TexelSize.y < 0)
             uv.y = 1-uv.y;
         #endif
     
         o.uv[1] = uv;
     
         return o;
     }

     float4 fragDCheap(v2fd i) : SV_Target 
     {    
         // inspired by borderlands implementation of popular "sobel filter"

         float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv[1]));
         float4 depthsDiag;
         float4 depthsAxis;

         float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;

         depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist, _CameraDepthTexture_ST))); // TR
         depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist*float2(-1,1), _CameraDepthTexture_ST))); // TL
         depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist*float2(-1,1), _CameraDepthTexture_ST))); // BR
         depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist, _CameraDepthTexture_ST))); // BL

         depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist*float2(0,1), _CameraDepthTexture_ST))); // T
         depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist*float2(1,0), _CameraDepthTexture_ST))); // L
         depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist*float2(1,0), _CameraDepthTexture_ST))); // R
         depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist*float2(0,1), _CameraDepthTexture_ST))); // B

         depthsDiag -= centerDepth;
         depthsAxis /= centerDepth;

         const float4 HorizDiagCoeff = float4(1,1,-1,-1);
         const float4 VertDiagCoeff = float4(-1,1,-1,1);
         const float4 HorizAxisCoeff = float4(1,0,0,-1);
         const float4 VertAxisCoeff = float4(0,1,-1,0);

         float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
         float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;

         float SobelX = dot(SobelH, float4(1,1,1,1));
         float SobelY = dot(SobelV, float4(1,1,1,1));
         float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);

         Sobel = 1.0-pow(saturate(Sobel), _Exponent);
         return Sobel * lerp(tex2D(_MainTex, UnityStereoScreenSpaceUVAdjust(i.uv[0].xy, _MainTex_ST)), _BgColor, _BgFade);
     }

     // pretty much also just a sobel filter, except for that edges "outside" the silhouette get discarded
     //  which makes it compatible with other depth based post fx

     float4 fragD(v2fd i) : SV_Target 
     {    
         // inspired by borderlands implementation of popular "sobel filter"

         float centerDepth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1], _CameraDepthTexture_ST)));
         float4 depthsDiag;
         float4 depthsAxis;

         float2 uvDist = _SampleDistance * _MainTex_TexelSize.xy;

         depthsDiag.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist, _CameraDepthTexture_ST))); // TR
         depthsDiag.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist*float2(-1,1), _CameraDepthTexture_ST))); // TL
         depthsDiag.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist*float2(-1,1), _CameraDepthTexture_ST))); // BR
         depthsDiag.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist, _CameraDepthTexture_ST))); // BL

         depthsAxis.x = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist*float2(0,1), _CameraDepthTexture_ST))); // T
         depthsAxis.y = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist*float2(1,0), _CameraDepthTexture_ST))); // L
         depthsAxis.z = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]+uvDist*float2(1,0), _CameraDepthTexture_ST))); // R
         depthsAxis.w = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, UnityStereoScreenSpaceUVAdjust(i.uv[1]-uvDist*float2(0,1), _CameraDepthTexture_ST))); // B

         // make it work nicely with depth based image effects such as depth of field:
         depthsDiag = (depthsDiag > centerDepth.xxxx) ? depthsDiag : centerDepth.xxxx;
         depthsAxis = (depthsAxis > centerDepth.xxxx) ? depthsAxis : centerDepth.xxxx;

         depthsDiag -= centerDepth;
         depthsAxis /= centerDepth;

         const float4 HorizDiagCoeff = float4(1,1,-1,-1);
         const float4 VertDiagCoeff = float4(-1,1,-1,1);
         const float4 HorizAxisCoeff = float4(1,0,0,-1);
         const float4 VertAxisCoeff = float4(0,1,-1,0);

         float4 SobelH = depthsDiag * HorizDiagCoeff + depthsAxis * HorizAxisCoeff;
         float4 SobelV = depthsDiag * VertDiagCoeff + depthsAxis * VertAxisCoeff;

         float SobelX = dot(SobelH, float4(1,1,1,1));
         float SobelY = dot(SobelV, float4(1,1,1,1));
         float Sobel = sqrt(SobelX * SobelX + SobelY * SobelY);

         Sobel = 1.0-pow(saturate(Sobel), _Exponent);
         return Sobel * lerp(tex2D(_MainTex, UnityStereoScreenSpaceUVAdjust(i.uv[0].xy, _MainTex_ST)), _BgColor, _BgFade);
     }

     half4 fragRobert(v2f i) : SV_Target {                
         half4 sample1 = tex2D(_CameraDepthNormalsTexture, i.uv[1].xy);
         half4 sample2 = tex2D(_CameraDepthNormalsTexture, i.uv[2].xy);
         half4 sample3 = tex2D(_CameraDepthNormalsTexture, i.uv[3].xy);
         half4 sample4 = tex2D(_CameraDepthNormalsTexture, i.uv[4].xy);

         half edge = 1.0;
     
         edge *= CheckSame(sample1.xy, DecodeFloatRG(sample1.zw), sample2);
         edge *= CheckSame(sample3.xy, DecodeFloatRG(sample3.zw), sample4);

         return edge * lerp(tex2D(_MainTex, i.uv[0]), _BgColor, _BgFade);
     }
 
     half4 fragThin (v2f i) : SV_Target
     {
         half4 original = tex2D(_MainTex, i.uv[0]);
     
         half4 center = tex2D (_CameraDepthNormalsTexture, i.uv[1]);
         half4 sample1 = tex2D (_CameraDepthNormalsTexture, i.uv[2]);
         half4 sample2 = tex2D (_CameraDepthNormalsTexture, i.uv[3]);
     
         // encoded normal
         half2 centerNormal = center.xy;
         // decoded depth
         float centerDepth = DecodeFloatRG (center.zw);
     
         half edge = 1.0;
     
         edge *= CheckSame(centerNormal, centerDepth, sample1);
         edge *= CheckSame(centerNormal, centerDepth, sample2);
         
         return edge * lerp(original, _BgColor, _BgFade);
     }
 
     ENDCG 
 
 Subshader {
  Pass {
       ZTest Always Cull Off ZWrite Off

       CGPROGRAM
       #pragma vertex vertThin
       #pragma fragment fragThin
       ENDCG
   }
  Pass {
       ZTest Always Cull Off ZWrite Off

       CGPROGRAM
       #pragma vertex vertRobert
       #pragma fragment fragRobert
       ENDCG
   }
  Pass {
       ZTest Always Cull Off ZWrite Off

       CGPROGRAM
       #pragma target 3.0   
       #pragma vertex vertD
       #pragma fragment fragDCheap
       ENDCG
   }
  Pass {
       ZTest Always Cull Off ZWrite Off

       CGPROGRAM
       #pragma target 3.0   
       #pragma vertex vertD
       #pragma fragment fragD
       ENDCG
   }
  Pass {
       ZTest Always Cull Off ZWrite Off

       CGPROGRAM
       #pragma target 3.0   
       #pragma vertex vertLum
       #pragma fragment fragLum
       ENDCG
   }
 }

 Fallback off
 
 } // shader


Sample scene download

Comment

People who like this

0 Show 0
10 |3000 characters needed characters left characters exceeded
â–¼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users

0 Replies

· Add your reply
  • Sort: 

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.

Follow this Question

Answers Answers and Comments

501 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

Unexpected symbol error in shader script 0 Answers

Efficient passing variable from Unity script to shader 0 Answers

How to change the alpha of instantiated object with custom shader. 0 Answers

OnRenderImage copy parts of a rendertexture to the destination 0 Answers

RenderTexture Scope Effect 0 Answers


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges