Issue with float3 parameter in my shader

Hello, while I was attempting to write a simple shader, I encountered issues with my float3 parameter named DiffuseLightDirection : For some reason it gets optimised out (propably replaced by a constant) even if it is actually used in one line of code.
Here’s the shader’s HLSL code:

   #if OPENGL
	#define SV_POSITION POSITION
	#define VS_SHADERMODEL vs_3_0
	#define PS_SHADERMODEL ps_3_0
#else
	#define VS_SHADERMODEL vs_4_0_level_9_1
	#define PS_SHADERMODEL ps_4_0_level_9_1
#endif
matrix World;
matrix View;
matrix Projection;

float4 AmbientColor = float4(1, 1, 1, 1);
float AmbientIntensity = 0.1;

float4x4 WorldInverseTranspose;

float3 DiffuseLightDirection;
float4 DiffuseColor = float4(1, 1, 1, 1);
float DiffuseIntensity = 1.0;

struct VertexShaderInput
{
    float4 Position : POSITION0;
    float4 Normal : NORMAL0;
};

struct VertexShaderOutput
{
    float4 Position : POSITION0;
    float4 Color : COLOR0;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;
    float4 worldPosition = mul(input.Position, World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);
    float4 normal = mul(input.Normal, WorldInverseTranspose);
    float lightIntensity = dot(normal, DiffuseLightDirection);
    output.Color = saturate(DiffuseColor * DiffuseIntensity * lightIntensity);
    return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
    return saturate(input.Color + AmbientColor * AmbientIntensity);
}
technique Ambient
{
    pass Pass1
    {
        VertexShader = compile VS_SHADERMODEL VertexShaderFunction();
        PixelShader = compile PS_SHADERMODEL PixelShaderFunction();
    }
}

And here’s my drawing C# function:

void DrawModelEffect(Model Model,ModelMatrices matrices,Effect effect)
        {
            foreach(ModelMesh mesh in Model.Meshes)
            {
                foreach(ModelMeshPart part in mesh.MeshParts)
                {
                    part.Effect = effect;
                    effect.Parameters["View"].SetValue(matrices.view);
                    effect.Parameters["Projection"].SetValue(matrices.projection);
                    effect.Parameters["World"].SetValue(matrices.translation * mesh.ParentBone.Transform);
                    AmbientShader.Parameters["AmbientColor"].SetValue(AmbientColor.ToVector4());
                    AmbientShader.Parameters["AmbientIntensity"].SetValue(AmbientIntensity);
                    AmbientShader.Parameters["DiffuseLightDirection"].SetValue(new Vector3(1,1,0));
                    Matrix worldInverseTransposeMatrix = Matrix.Transpose(Matrix.Invert(mesh.ParentBone.Transform * matrices.translation));
                    effect.Parameters["WorldInverseTranspose"].SetValue(worldInverseTransposeMatrix);
                }
                mesh.Draw();
            }
        }

For some reason the AmbientShader.Parameters dictionary doesn’t contain the parameter I wish to change (as seen in the picture below)

pic1

Thanks for your attention.

just for completeness: Did you try to rebuild the shader in the content window in case you just added that parameter?

Of course.

I would just try the following:

  • assign an initial value in shader code

  • make it a float4 or cast the normal to float3 in dot - maybe not related but the second param in “dot” is expected to have the same dimensions as the first … there should be a warning upon shader building actually

The only float3 I could see in your hlsl code is : DiffuseLightDirection
and it is not used anywhere in your HLSL code, if you don’t assign and use it in any operation it gets optimized and removed since no one is using it.

I had the same problem with some shaders I am working on, and my variables get optimized because I commented the line of code that was using the variable, so my C# program crashed, took me some time to find out why, so you need to use that parameter somewhere, anywhere in any operation, otherwise it gets deleted. Even if you assign any value to it, if there is no single operation with that variable that will affect the pixel or vertex shader it will get removed.

he uses it in the dotproduct in VS

1 Like

Thanks for reminding me that my posts had missing information.

Just as reiti.net says, the DiffuseLightDirection parameter is used in the dot product:

    float lightIntensity = dot(normal, DiffuseLightDirection);

can you try to change:

vs_4_0_level_9_1 to vs_4_0_level_9_3
and
ps_4_0_level_9_1 to ps_4_0_level_9_3

?

I found many times that I couldn’t make it work with 9_1, i am not sure why.

I will try this later. Will update the situation by a new post in this thread.

It is not the only parameter that is missing. From what I can see you are missing WorldInverseTranspose, DiffuseLightDirection, DiffuseColor, DiffuseIntensity. I think it is likely related to the fact that you are using a float4 normal instead of a float3 and that you then try to take the dot of a float4 and a float3 in this line:

float lightIntensity = dot(normal, DiffuseLightDirection);

If you change the normal to be a float3 then the compiler will optimize WorldInverseTranspose to a float3x3 matrix which I have experienced can cause a crash later on in effect.Apply() because the parameters don’t match what Monogame is expecting. I think what has worked for me is to set it as a float3x3 or to put it as the last parameter in the file.