1
\$\begingroup\$

I recently asked a question about the creating an accurate Depth Intersection Shader.

When creating this in a fragment / vertex shader it could be achieved by the following code

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;
        sampler2D _CameraDepthTexture;
        fixed4 _Color;
        fixed4 _GlowColor;
        float _FadeLength;

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

            return o;
        }

        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);

            return fixed4(lerp(tex2D(_MainTex, i.uv) * _Color, _GlowColor, pow(intersect, 4)));
        }
        ENDCG
    }
}

However, when I try to put the same logic into a surface shader, the result does not show any depth intersections.

SubShader {
    Blend SrcAlpha OneMinusSrcAlpha
    ZWrite On

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

    CGPROGRAM
    // Physically based Standard lighting model, and enable shadows on all light types
    #pragma surface surf Standard fullforwardshadows alpha:fade

    // 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;
    sampler2D _CameraDepthTexture;
    fixed4 _Color;
    fixed4 _GlowColor;
    float _FadeLength;

    // Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
    // See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
    // #pragma instancing_options assumeuniformscaling
    UNITY_INSTANCING_CBUFFER_START(Props)
        // put more per-instance properties here
    UNITY_INSTANCING_CBUFFER_END

    void surf (Input IN, inout SurfaceOutputStandard o) {
        float2 screenuv = IN.screenPos.xy / _ScreenParams.xy;
        float screenDepth = Linear01Depth(tex2D(_CameraDepthTexture, screenuv));
        float diff = screenDepth - Linear01Depth(IN.screenPos.z);
        float intersect = 0;

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

        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
}
\$\endgroup\$
0
\$\begingroup\$

Credits to bgolus, a member of the Unity forums, as the code is still a little bewildering to me.

It is possible.

Shader "Intersection Shaders/Surface Intersection Shader" {
    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, 2)) = 1
    }
    SubShader {
        Blend SrcAlpha OneMinusSrcAlpha
        ZWrite On

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

        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows alpha:fade
        #pragma target 3.0

        sampler2D _MainTex;

        struct Input {
            float2 uv_MainTex;
            float4 screenPos;
            float3 worldPos;
        };

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

        UNITY_INSTANCING_BUFFER_START(Props)
        UNITY_INSTANCING_BUFFER_END(Props)

        void surf (Input IN, inout SurfaceOutputStandard o) {
            float sceneZ = LinearEyeDepth(SAMPLE_DEPTH_TEXTURE_PROJ(_CameraDepthTexture, UNITY_PROJ_COORD(IN.screenPos)));
            float surfZ = -mul(UNITY_MATRIX_V, float4(IN.worldPos.xyz, 1)).z;
            float diff = sceneZ - surfZ;
            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"
}
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.