0
\$\begingroup\$

I wrote the following surface shader. The idea is to increase the Z depth value of vertices, after projection.

Shader "Custom/Highlighted"
{
    Properties
    {
        _Color ("Main Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }

        CGPROGRAM
        #pragma surface surf Lambert
        #pragma vertex vert 

        struct Input
        {
            float4 pos: SV_POSITION;
            float4 color : COLOR;           
        };
        
        void vert(inout appdata_full v, out Input o) 
        {
            UNITY_INITIALIZE_OUTPUT(Input, o);       //
            o.pos = mul(UNITY_MATRIX_MVP, v.vertex); // does not work
            o.pos.z += 0.001;                        //
            o.color = v.color;                       //
        }

        fixed4 _Color;
        void surf (Input IN, inout SurfaceOutput o)
        {
            o.Albedo = _Color.rgb;
            o.Alpha = _Color.a;
        }
        ENDCG
    }
    Fallback "Diffuse"
}

The shader compiles, and objects are rendered correctly, however it's like the z depth value is not modified at all (what is inside vert is ineffective).

Here is the equivalent code as a fragment shader (which work perfectly) :

struct vertInput {
    float4 pos : POSITION;
    float4 color : COLOR0;
    float4 uv : TEXCOORD1;
};

struct vertOutput {
    float4 pos : SV_POSITION;
    fixed4 color : COLOR0;
};

vertOutput vert (vertInput input)
{
    vertOutput o;
    o.pos = mul(UNITY_MATRIX_MVP, input.pos);
    o.pos.z += 0.001;
    o.color = input.color;
    return o;
}
\$\endgroup\$
5
  • \$\begingroup\$ Did you mean to write to v.vertex, which is the vertex position that gets used for projection and depth testing? \$\endgroup\$ Commented Jan 21, 2022 at 1:09
  • \$\begingroup\$ AFAIK v.vertex is before projection, I would like to modify the properties after projection (at that moment, z property should be what is written to depth buffer) \$\endgroup\$ Commented Jan 21, 2022 at 1:16
  • \$\begingroup\$ So, transform it to post-projection space, modify it, then transform it back to continue down the pipeline. I've done this in a previous answer. \$\endgroup\$ Commented Jan 21, 2022 at 3:44
  • \$\begingroup\$ I see what you mean, that's a little weird but it should work. Btw you have 2500+ answers, can you add a link to the one I can use as reference ? \$\endgroup\$ Commented Jan 21, 2022 at 10:12
  • 1
    \$\begingroup\$ Only four that use custom vertex functions in a Surface Shader, so that narrows down your search space. Here's one that shows transforming into view space, modifying, and transforming back — you can extend that to go all the way into post-projection space. If you just want a depth bias though, there are built in methods for that (see the "Offset" section). \$\endgroup\$ Commented Jan 21, 2022 at 12:29

1 Answer 1

1
\$\begingroup\$

As suggested by DMGregory, one solution to apply depth bias is to use the Offset keyword :

Shader "Custom/Highlighted"
{
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Offset 0, -1 //pulls the polygon closer to the camera
        ...
    }
    ...
}

Another way is to transform vertex into view space, modify it as wanted, then transform back, as explained here.

\$\endgroup\$

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.