Bug in shader compiler

Got a really nasty bug in the shader compiler that is killing my progress.

In my directional light shader I pass in two floats from c# which define this particular directional light as the sun or the moon

These are output in the material definition and used in the final colour composition pass.

But I cannot use one of them, just one,

If I use this code

output.Material = float4(SpecularIntensity, Shininess, MoonLit, SunLit);

I get the error

X5204 Read of uninitialized components, in r3 :r/x/0 g/y/1 b/z/2 a/w/3

If I change it to …

output.Material = float4(SpecularIntensity, Shininess, MoonLit, 1);

It compiles fine.

SunLit is defined as

float SunLit = 0.0f;

This of course makes no sense

Any ideas guys?

More data.

If I change it to

output.Material = float4(SpecularIntensity, Shininess, 0.0f, SunLit);

It compiles
WTF

try to make change to this with out “f” postfix
float SunLit = 0.0

Made no difference.

This is just stupid

try

float SunLit;
SunLit=0.0f;

the shader compiler is quite picky, but you’re not into deep trouble until you have to make it work on GL platforms.

This of course makes no sense

float4 var = float4( , , , has uninitialized component SunLit);
Basically sunlit is null as far as the error goes.

.
.

If the variable sunlit is a floating constant defined in the shader you could declare it static.
However that is only good for testing because gl or dx will not allow that and ignore it (i forget which one).

So instead declare it in the shader …

float SunLit;

Then from game1 after you load the effect initialize the variable …

myEffect.Parameters["SunLit"].SetValue(0.0f);

.
you should probably do it that way for all those values that are acting as if defaults because currently on the shader default values as a rule of thumb are unreliable and a easy way to cause yourself a bug that is really hard to find.

Also when debuging stuff like this in your shaders in the future if its really annoying.
Separate out the values like so.

float4 myvar = float4(1f,1f,1f,1f);
myvar.x = SpecularIntensity;
myvar.y = Shininess;
myvar.z = MoonLit;
myvar.w = SunLit;  // you should get a error here now.
// or on each line that has a unitialized value in the vs console window which tells you what line the error is on.

SunLit and MoonLit are both defined in the shader and are both setup in C#

I added SunLit last week and came up with a way of calculating when an object passes into the Earths shadow and is no longer lit by the sun. It worked perfectly in both my forward renderer and deferred renderer.

So I decided to add MoonLit to the deferred renderer.

Which is when this annoying bug came up.

The key point is that I can use either one of MoonLit or SunLit and it compiles, but if I use both it does not.

float4x4 World;
float4x4 View;
float4x4 Projection;
float4x3 WorldInverseTranspose;

float SunLit = 0.0;
float AlphaCut = 1.0;
float Shininess = 200;
float SpecularIntensity = 1;
float  DiffuseIntensity = 1;
float4 MaterialColour = float4(0,0,0,0);
float MoonLit = 1.0;


bool TestAlpha = false;

struct PixelShaderOutput
{
float4 Color : COLOR0;
float4 Normal : COLOR1;
float4 Depth : COLOR2;
float4 Material : COLOR3;
};

PixelShaderOutput MainPS(VertexShaderOutput input)
{
	PixelShaderOutput output;
	float4 colour = tex2D(textureSampler, input.TexCoord);
	if (TestAlpha)
	{
		if (colour.a < AlphaCut)
			discard;
	}
	output.Material = float4(SpecularIntensity, Shininess, MoonLit, SunLit);
	output.Color = DiffuseIntensity * colour * MaterialColour;			// output Color
	output.Color.a = 1.0f;                                
	output.Normal.rgb = 0.5f * (normalize(input.Normal) + 1.0f);		// transform normal domain
	output.Normal.a = 1.0f;
	output.Depth = float4(1, 1, 1, 1);
	output.Depth = input.Depth.x / input.Depth.y;                       // output Depth
	
	return output;
}

found a solution

Changed from ps_4_0_level_9_1 to ps_4_0