Skip to content

Instantly share code, notes, and snippets.

@smkplus
Last active October 8, 2023 03:58
Show Gist options
  • Save smkplus/49c39ed5e68244c03f86bf455084cdae to your computer and use it in GitHub Desktop.
Save smkplus/49c39ed5e68244c03f86bf455084cdae to your computer and use it in GitHub Desktop.

https://forum.unity.com/threads/accessing-depth-buffer-from-a-surface-shader.404380/

https://gamedev.stackexchange.com/questions/158243/surface-depth-intersection-shader#

Surface Shader:

Shader "Intersection/SimpleSurface" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _InvFade ("Soft Factor", Range(0.01,3.0)) = 1.0
    }
    SubShader {
        Tags { "Queue"="Transparent" "RenderType"="Transparent" }
        LOD 200
       
        CGPROGRAM
        // Physically based Standard lighting model, and enable shadows on all light types
        #pragma surface surf Standard vertex:vert alpha:fade nolightmap
 
        // Use shader model 3.0 target, to get nicer looking lighting
        #pragma target 3.0
 
        sampler2D _MainTex;
 
        struct Input {
            float2 uv_MainTex;
            float4 screenPos;
            float eyeDepth;
        };
 
        half _Glossiness;
        half _Metallic;
        fixed4 _Color;
 
        sampler2D_float _CameraDepthTexture;
        float4 _CameraDepthTexture_TexelSize;
       
        float _InvFade;
 
        void vert (inout appdata_full v, out Input o)
        {
            UNITY_INITIALIZE_OUTPUT(Input, o);
            COMPUTE_EYEDEPTH(o.eyeDepth);
        }
 
        void surf (Input IN, inout SurfaceOutputStandard o) {
            // Albedo comes from a texture tinted by color
            fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
            o.Albedo = c.rgb;
            // Metallic and smoothness come from slider variables
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
 
            float rawZ = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos));
            float sceneZ = LinearEyeDepth(rawZ);
            float partZ = IN.eyeDepth;
 
            float fade = 1.0;
            if ( rawZ > 0.0 ) // Make sure the depth texture exists
                fade = saturate(_InvFade * (sceneZ - partZ));
 
            o.Alpha = c.a * fade;
        }
        ENDCG
    }
}

Glow Surface:

Shader "Intersection/Surface" {
    Properties {
        _Color ("Color", Color) = (1,1,1,1)
        _MainTex ("Albedo (RGB)", 2D) = "white" {}
        _Glossiness ("Smoothness", Range(0,1)) = 0.5
        _Metallic ("Metallic", Range(0,1)) = 0.0
        _GlowColor("Glow Color", Color) = (1, 1, 1, 1)
        _FadeLength("Fade Length", Range(0, 5)) = 1
    }
    SubShader {
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite On

        Tags
        {
            "RenderType" = "Transparent"
            "Queue" = "Transparent"
        }

        CGPROGRAM
        #pragma surface surf Standard vertex:vert alpha:fade nolightmap
 
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
            float4 screenPos;
            float eyeDepth;
        };

        half _Glossiness;
        half _Metallic;
        sampler2D _CameraDepthTexture;
        fixed4 _Color;
        fixed4 _GlowColor;
        float _FadeLength;

		void vert (inout appdata_full v, out Input o)
        {
            UNITY_INITIALIZE_OUTPUT(Input, o);
            COMPUTE_EYEDEPTH(o.eyeDepth);
        }


        void surf (Input IN, inout SurfaceOutputStandard o) {
            float rawZ = SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos));
            float sceneZ = LinearEyeDepth(rawZ);
            float partZ = IN.eyeDepth;
			float diff = (sceneZ - partZ);

            float intersect = 1 - saturate(diff / _FadeLength);

            fixed4 col = fixed4(lerp(tex2D(_MainTex, IN.uv_MainTex) * _Color, _GlowColor, pow(intersect, 4)));
            o.Albedo = col.rgb;
            o.Alpha = col.a;
            o.Metallic = _Metallic;
            o.Smoothness = _Glossiness;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

Fragment Shader:

Shader "Intersection/Fragment"
{
    Properties
    {
        _Color("Color", Color) = (0,0,0,0)
        _GlowColor("Glow Color", Color) = (1, 1, 1, 1)
        _FadeLength("Fade Length", Range(0, 2)) = 0.15
    }
    SubShader
    {
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite On

        Tags
        {
            "RenderType" = "Transparent"
            "Queue" = "Transparent"
        }

        Pass
        {
            CGPROGRAM
            #pragma target 3.0
            #pragma vertex vert
            #pragma fragment frag

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert(appdata v, out float4 vertex : SV_POSITION)
            {
                v2f o;
                vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);

                return o;
            }

            sampler2D _CameraDepthTexture;
            fixed4 _Color;
            fixed3 _GlowColor;
            float _FadeLength;

            fixed4 frag (v2f i, UNITY_VPOS_TYPE vpos : VPOS) : SV_Target
            {
                float2 screenuv = vpos.xy / _ScreenParams.xy;
                float screenDepth = Linear01Depth(tex2D(_CameraDepthTexture, screenuv));
                float diff = screenDepth - Linear01Depth(vpos.z);
                float intersect = 0;

                if(diff > 0)
                    intersect = 1 - smoothstep(0, _ProjectionParams.w * _FadeLength, diff);

                fixed4 glowColor = fixed4(lerp(_Color.rgb, _GlowColor, pow(intersect, 4)), 1);

                fixed4 col = _Color * _Color.a + glowColor;
                col.a = _Color.a;
                return col;
            }
            ENDCG
        }
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment