worldPos not set correctly if SHADER_API_D3D11 is defined

Okay, the issue I had didn’t exist, so I am converting the thread to the real issue. If SHADER_API_D3D11 is defined, worldPos is not filled in the standard shader. Here is a simple shader that will show the issue.

Shader "Custom/Error"
{
    Properties
    {
        _Pos ("Color", Vector) = (0,0,0,0)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 200
      
        CGPROGRAM
        #pragma surface surf Standard fullforwardshadows
        #pragma target 3.0

        struct Input
        {
            float3 worldPos;
        };

        fixed4 _Pos;

        void surf (Input IN, inout SurfaceOutputStandard o)
        {
            float blend = 0;

            #ifdef SHADER_API_D3D11
                blend = distance(IN.worldPos, _Pos.xyz);
            #endif

            o.Albedo = blend;
        }
        ENDCG
    }
    FallBack "Diffuse"
}

Add the material to an object, and try changing _Pos. You will see that it applies the same value to the whole object, when it should actually show a spherical gradient from _Pos.

Does it actually get compiled? Does the shader have this multi compile line:
#pragma multi_compile DISSOLVE_BASIC DISSOLVE_ORIGIN DISSOLVE_ARRAY

Also, #elif is equivalent to (else)#if, not to (else)#ifdef. For that use #elif defined(KEYWORD)

Yup, it get compiled, no error. The effect just doesn’t work in the first case. And this is indeed my multi-compile line.

Can you make a simple shader that outputs one color if SHADER_API_D3D11 is defined and another if it’s not? Then you can at least check whether this is set and when.

Okay, I finally fixed it. But it doesn’t make any sense.

Following your last reply, I wrote a small shader doing a poor blend between two color, in the exact same multi_compile. No issue. So I start adding the features of my shader one by one, thoroughly testing each time. Until there is pretty much everything, and it breaks. I decide to only push one point in my structured buffer, and I drive it from script thanks to a transform I have in my scene. And here, I realize that when I approach the position (1,0,0), I have my effect, kind of, but the same value is applied to everything. Takes me a while to really understand what’s going on. in my code, I replace IN.worldPos by an hardcoded value, say, (-1,2,5), and when I test the effect, I have the exact same result.

So basically, for some reason, if I define SHADER_API_D3D11, IN.worldPos contains a default value of (1,0,0). For now, I got it working by creating my custom vertex position by defining it in my own custom vertex shader. I think it’s not the best looking solution, but for now it works.

I will write a shader to see if I can reproduce the issue in a smaller scale, and fill a bug report if necessary. Thanks for your help. :slight_smile:

edit : updated the first message to reflect the real issue