glGetUniformLocation Failing on uniform

Started by
2 comments, last by OmniRa 9 years, 10 months ago

Hi, i have this fragment shader and glGetUniformLocation is returning -1 for a few entries. one of which is "camera_position".

Im not sure why this is happening, it's working for other variables like "num_directional_lights" & "num_point_lights". Is there any reason it would fail for that particular one. The shader doesn't appear to have an compilation errors.

This is the fragment shader:


//
// version
//
#version 330

//
// constants
//
const int NAX_DIRECTIONAL_LIGHTS = 2;
const int MAX_POINT_LIGHTS =       2;
const int MAX_SPOT_LIGHTS =        2;

//
// structs
//
struct DIRECTIONAL_LIGHT
{
	vec3  colour;
	float ambientIntensity;
	float diffuseIntensity;
	vec3  direction;
};

struct POINT_LIGHT
{
	vec3  colour;
	float ambientIntensity;
	float diffuseIntensity;
	float constantAttenuation;
	float linearAttenuation;
	float exponetialAttenuation;
};

struct SPOT_LIGHT
{
	vec3  colour;
	float ambientIntensity;
	float diffuseIntensity;
	float constantAttenuation;
	float linearAttenuation;
	float exponetialAttenuation;
	vec3  direction;
	float cutoff;
};

//
// uniforms
//
uniform vec3              camera_position;
uniform sampler2D         texture0;
uniform int               num_directional_lights;
uniform int               num_point_lights;
uniform int               num_spot_lights;
uniform DIRECTIONAL_LIGHT directional_light [NAX_DIRECTIONAL_LIGHTS];
uniform POINT_LIGHT       point_light       [MAX_POINT_LIGHTS];
uniform SPOT_LIGHT        spot_light        [MAX_SPOT_LIGHTS];

//
// in attributes
//
in vec4 frag_colour;
in vec2 frag_texCoord0;
in vec3 frag_normal;
in vec3 frag_worldPos;

//
// out attributes
//
out vec4 out_colour;

//
// functions
//
vec4 CalculateDirectionalLight(void)
{
	vec4 totalLight = vec4(0, 0, 0, 0);

	// temp
	// ====
	float specularIntensity = 0.0;
	float specularPower =     0.0;
	// ====

	for (int i = 0; i < num_directional_lights; ++i)
	{
		vec4  ambientColour =  vec4(directional_light[i].colour, 1.0) * directional_light[i].ambientIntensity;
		float diffuseFactor =  dot(frag_normal, -directional_light[i].direction);
		vec4  diffuseColour =  vec4(0, 0, 0, 0);
		vec4  specularColour = vec4(0, 0, 0, 0);

		if (diffuseFactor > 0.0)
		{
			vec3  toEye =          normalize(camera_position - frag_worldPos);
			vec3  lightReflect =   normalize(reflect(directional_light[i].direction, frag_normal));
			float specularFactor = pow(dot(toEye, lightReflect), specularPower);

			if (specularFactor > 0.0)
				specularColour = vec4(directional_light[i].colour, 1.0) * specularIntensity * specularFactor;
		}

		totalLight += (ambientColour + diffuseColour + specularColour);
	}

	return totalLight;
}

vec4 CalculatePointLight(void)
{
	vec4 totalLight = vec4(0, 0, 0, 0);

	for (int i = 0; i < num_point_lights; ++i)
	{
		// ...
		// TODO
	}

	return totalLight;
}

vec4 CalculateSpotLight(void)
{
	vec4 totalLight = vec4(0, 0, 0, 0);

	for (int i = 0; i < num_spot_lights; ++i)
	{
		// ...
		// TODO
	}

	return totalLight;
}

//
// entry
//
void main(void)
{
	vec4 totalLight = CalculateDirectionalLight();
	totalLight +=     CalculatePointLight();
	totalLight +=     CalculateSpotLight();

	out_colour = texture(texture0, frag_texCoord0.st) * frag_colour * totalLight;
}

Will conintue looking myself, but time for bed :( TY for any help

Advertisement

That variable has been optimized out by the shader compiler, because it's not actually used. If the compiler realizes that a uniform isn't used, it's free to delete it.

If you trace your variable through your code, it looks like it's used - it looks like it should influence the result of your shader:


vec3  toEye =          normalize(camera_position...);
float specularFactor = pow(...toEye...), specularPower);
specularColour = ... * specularFactor;
totalLight += ...specularColour;
return totalLight;

Except that float specularPower = 0.0; so:


vec3  toEye =          normalize(camera_position...);
float specularFactor = pow(...toEye...), 0); // anything raised to the power of zero is 1
//So the above two lines get optimized to:
float specularFactor = 1; 

And thus camera_position isn't used, so, it's correct that you can't locate it.

It's worth noting that you're allowed to pass a uniform location of -1 into the glUniform* functions, so in practice you don't really have to worry about whether the uniform exists or not. Just pass the location you got in and all will be well.

SlimDX | Ventspace Blog | Twitter | Diverse teams make better games. I am currently hiring capable C++ engine developers in Baltimore, MD.

Thankyou smile.png

I thought the optimizer would just remove variables that didn't get referenced in the code, I didn't realise it was that good at removing unused things!

I changed some variables to make sure they have influence on the result and it works now.

Ty

This topic is closed to new replies.

Advertisement