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\$

1 Answer 1

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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .