# Very strange GLSL problem. Objects not rendering when accessing shadowMaps

## Recommended Posts

I have a very strange problem with rendering a scene, even with one point shadow map.

NOTE: This problem has been solved. Apparently I was trying to read my cubeMaps into an array of samplerCubes, but this does not work for me for some reason.

I am rendering a scene with one floor with a shader which recieves a singe shadow cube map, and 9 cubes with a light shader with no shadow map.

Whenever I render the scene without testing for the shadow map depth comparison, it renders just fine (but without the shadows), but if i render the scene WITH shadow map depth testing, the floor just... disappears

It doesn't give me an error message or anything.

Here are pictures of what I am talking about:

Here is the GLSL code for the floor object (specular code omitted):

#version 400

in vec2 outUV;
in vec3 outNormals;
in vec4 outPosition;
in vec4 outEyePosition;

out vec4 outColor;

uniform vec4 diffuseColor;
uniform vec4 specularColor;
uniform float diffuseAmount;
uniform float specularAmount;
uniform float specularOffset;
uniform float ambientAmount;
uniform float emmisionAmount;
uniform unsigned int specularHardness;

uniform vec3 lightPositions[8];
uniform vec3 lightColors[8];
uniform float lightIntensities[8];
uniform float lightDistances[8];

uniform sampler2D diffuse;

vec3 calcPointLightColor(int index, inout vec3 lightDirection, vec3 viewDirection, vec3 currentNormal, float inShadow)
{
float lightDistance;
float lightIntensity;

vec3 lightColor;
lightColor = vec3(0.0, 0.0, 0.0);

{
lightDistance = lightDistances[index];

lightDirection = outPosition.xyz - lightPositions[index];
lightDistance = length(lightDirection) / lightDistance;
lightDistance = clamp(lightDistance, 0.0, 1.0);
lightDistance = (lightDistance * -1.0) + 1.0;
lightDirection = normalize(lightDirection);

lightIntensity = dot(currentNormal, -lightDirection);
if(lightIntensity < 0.0)
{
lightIntensity = 0.0;
}
lightIntensity = lightIntensity * lightDistance;

lightColor = vec3((lightColors[index] * lightIntensities[index]) * lightIntensity);
}

return lightColor;
}

{
float lengthToPixel;

vec3 directionToShadowMap = outPosition.xyz - lightPositions[index];

{
}
else
{
}
}

void main()
{
vec3 viewDirection;
vec3 currentNormal;
vec3 lightDirections[8];

vec4 finalColor;
vec4 diffuseColorFinal;

diffuseColorFinal = diffuseColor * diffuseAmount;

currentNormal = normalize(outNormals);

viewDirection = outPosition.xyz - outEyePosition.xyz;

viewDirection = normalize(viewDirection);
viewDirection = -viewDirection;

finalColor += vec4(calcPointLightColor(0, lightDirections[0], viewDirection, currentNormal, inShadow[0]), 1.0);
finalColor.a = 1.0;

finalColor = finalColor * vec4(texture(diffuse, outUV).rgb, 1.0);

finalColor = finalColor * diffuseColorFinal;

outColor = finalColor;
}

So yeah. The shadow maps are fine, I debugged them by outputting to a quad, and they look fine. They are point light shadow maps, so they check for distance stored in the red component, instead of a depth component, for spherical distance.

I am guessing this is just a runtime GLSL error, but I cannot figure out what I am doing wrong.

I am following this tutorial: http://ogldev.atspace.co.uk/www/tutorial43/tutorial43.html

Edited by Solid_Spy

##### Share on other sites

Why are you allowing lights to modify the alpha component of the diffuse value?

Why is specular not affected by shadows?

Why are you lighting via 8 speculars but only 1 diffuse?

Why is your shadowing term the reverse of what it should be?  It’s not a boolean, it is a factor. 1.0 means completely not in shadows.  0.0 means totally in shadows.

Your link is not valid so I can’t compare with what they are doing, but there are no worthwhile tutorials that teach using 1 = in shadow and 0 = not in shadow.

Why don’t you see if you are actually drawing the floor when you have shadow maps enabled?

If you are, why not remove code section-by-section until it appears?

If it turns out that it is not rendering because of the alpha value, why are you using alpha testing for opaque objects?

L. Spiro

Edited by L. Spiro

##### Share on other sites

"Why are you allowing lights to modify the alpha component of the diffuse value?"

Well I have to output a vec4 color to the back buffer, in case I ever use alpha blending, so I add an extra 1.0 to the end of the light value when adding it to the final color. I changed the default color back to vec4(0.0, 0.0, 0.0, 1.0), but no change. I'm not using alpha blending, but I plan to with other objects in the future.

"Why is specular not affected by shadows?"

I want to test it with diffuse first before testing it with specular. If the diffuse doesn't work, then the specular wont work either. It would be a wasted effort.

"Why are you lighting via 8 speculars but only 1 diffuse?"

My bad. At the moment I left it in there regardless since i'm only testing the diffuse. I commented it out for now.

"Why is your shadowing term the reverse of what it should be?  It’s not a boolean, it is a factor. 1.0 means completely not in shadows.  0.0 means totally in shadows.

Your link is not valid so I can’t compare with what they are doing, but there are no worthwhile tutorials that teach using 1 = in shadow and 0 = not in shadow."

I don't know what is wrong with the link. It's ogldev.atspace.co.uk, the 43 tutorial. I have no excuse for the floating point, other than that i've never used bools in glsl and was more familiar with floats, I changed it to a bool.

"Why don’t you see if you are actually drawing the floor when you have shadow maps enabled?

If you are, why not remove code section-by-section until it appears?

I've tried that multiple times, and the only like of code that makes things work when being commented out is this one:

bool shadowMapComparison(int index)
{
float lengthToPixel;

vec3 directionToShadowMap = outPosition.xyz - lightPositions[index];

//The culprit

{
}
else
{
}
}


"If it turns out that it is not rendering because of the alpha value, why are you using alpha testing for opaque objects?"

The alpha value isn't doing anything, since i'm just adding 0.0 to 1.0, which gives 1.0 regardless, however I do plan on using this same shader for both alpha and opaque objects.

And I swear I am sending the texture over to it properly. This is the function I use in C++ to send the light data over to the shader for every object:

void RenderingEngine::UpdateRenderQueueNodeLightData(RenderQueueNode& renderQueueNode,
{
GLuint location;

glm::vec3 lightPosition;
glm::vec3 lightColor;

float lightIntensity;
float lightDistance;

for(unsigned int i = 0; i < 8; i++)
{
lightPosition =
renderQueueNode.renderingComponent->GetLight(i).lightPosition;

glUniform3fv(location, 1, (GLfloat*)&lightPosition);
}

for(unsigned int i = 0; i < 8; i++)
{
lightColor =
renderQueueNode.renderingComponent->GetLight(i).lightColor;

glUniform3fv(location, 1, (GLfloat*)&lightColor);
}

for(unsigned int i = 0; i < 8; i++)
{
lightIntensity =
renderQueueNode.renderingComponent->GetLight(i).lightIntensity;

glUniform1f(location, lightIntensity);
}

for(unsigned int i = 0; i < 8; i++)
{
lightDistance =
renderQueueNode.renderingComponent->GetLight(i).lightDistance;

glUniform1f(location, lightDistance);
}

{
glUniform1i(location, 12);

glActiveTexture(GL_TEXTURE0 + 12);

break;
default:
break;
}
}

Edited by Solid_Spy

##### Share on other sites

I don't know what is wrong with the link. It's ogldev.atspace.co.uk, the 43 tutorial. I have no excuse for the floating point, other than that i've never used bools in glsl and was more familiar with floats, I changed it to a bool.

That is exactly the opposite of what I said. Shadowing is not a boolean.

The alpha value isn't doing anything, since i'm just adding 0.0 to 1.0, which gives 1.0 regardless

That’s only true (partially) because your lighting is wrong.
finalColor = finalColor + calcPointLightColor(0, lightDirections[0], viewDirection, currentNormal, inShadow[0]);
should be:
finalColor *= calcPointLightColor(0, lightDirections[0], viewDirection, currentNormal, inShadow[0]);

But it’s not really true.
calcPointLightColor() returns [X, X, X, 1] if inShadow is not 0.0, and [X, X, X, 0] otherwise.  Whether you add (wrong) or multiply (correct), light is modifying your diffuse alpha in one condition or the other.

I've tried that multiple times, and the only like of code that makes things work when being commented out is this one:

Is this shader only being run on the ground?
If so, then you may have a compiler or linker error on that shader. You should be checking all OpenGL ES errors and compilation success religiously.

L. Spiro

##### Share on other sites

"That is exactly the opposite of what I said. Shadowing is not a boolean."

Ah, ok. For some reason I misunderstood what you said earlier. Will change back to float.

"That’s only true (partially) because your lighting is wrong.
finalColor = finalColor + calcPointLightColor(0, lightDirections[0], viewDirection, currentNormal, inShadow[0]);
should be:
finalColor *= calcPointLightColor(0, lightDirections[0], viewDirection, currentNormal, inShadow[0]);

But it’s not really true.
calcPointLightColor() returns [X, X, X, 1] if inShadow is not 0.0, and [X, X, X, 0] otherwise.  Whether you add (wrong) or multiply (correct), light is modifying your diffuse alpha in one condition or the other."

Ah, I see now. I'm gonna just use vec3's instead just cuz I won't really need the alpha for the lights. Though I'm a bit confused. Aren't lights supposed to be added together? If I multiply a red light(vec3(1.0, 0.0, 0.0)) with a blue light(vec3(0.0, 1.0, 0.0)), the lights should cancel out. First, I add all the colored lights together, then I multiply it against the diffuse. I try this and I get no artifacts.

I'm confused. Why would I need to normalize it? if a distance value in the r component of the shadowMap is 5.0 and is sent to shadowDistance, and the distance between the pixel and light is calculated to be 4.9 and is sent to lengthToPixel, I want to check that the distance value is greater than the shadow map value for it to be in shadow. This is exactly the way it is done in the tutorial. What is it that normalizing would do to change this? As far as I know only vectors can be normalized, not floats. I'm not quite sure what you mean.

"Is this shader only being run on the ground?"

Yes. Only the ground.

"If so, then you may have a compiler or linker error on that shader. You should be checking all OpenGL ES errors and compilation success religiously."

I check for errors using glGetShaderIV and glGetShaderInfoLog. I don't get any unless I have a typo or a missing semicolon. I've been error checking the shiznitz out of this thing, and I got nothing.

Edited by Solid_Spy

##### Share on other sites

UPDATE: Ok, apparently the shadow map ISN'T being sent to the shader for some reason -.- (even though the light data is, which is odd since it's in the same struct as the shadow map). I don't know why, but I tried projecting the shadow map onto the floor using:

    vec3 directionToShadowMap = outPosition.xyz - lightPositions[0];
finalColor = finalColor * vec4(texture(shadowCubeMaps[0], directionToShadowMap).r, 0.0, 0.0, 1.0);

but I get nothing but black.

It's very strange, because it was working previously. I will get back to you guys once I manage to even get the shadow map into the shader in the first place.

Edited by Solid_Spy

##### Share on other sites

Aren't lights supposed to be added together?

Yes but your variable names are confusing me (so yes your code was correct).
Why don’t you add them into a variable called “diffuseGather” and “specularGather”?
Then those get multiplied by the diffuse and specular, and then they are added together.
It is not against the law to make your code clear by using totally separate values to gather all your diffuse, and another value to gather all your specular, etc. When your variables are named, “finalColor” and “diffuseColorFinal”, it is pretty hard to follow the flow and to see what part of code is meant to do what.
In any case, you didn’t initialize finalColor and diffuseColorFinal to 0.

I'm confused. Why would I need to normalize it?

Because you are sampling a cube texture with it.
But I am going out of my mind all over the place in this topic for some reason. You don’t need to normalize to sample a cube texture. I am being retarded.

Ah, ok. For some reason I misunderstood what you said earlier. Will change back to float.

But you are still using it as a boolean. As I said. It is a factor.  1 = not in shadow.
Why?

fShadowFactor[0] = getShadow( 0 );
vec3 diffuseLightGather = vec3( 0.0, 0.0, 0.0 );
diffuseLightGather += calcLight( 0 ) * fShadowFactor[0];
diffuseLightGather += calcLight( 1 ) * fShadowFactor[1];
It’s a factor. You don’t if/else it like a boolean, you multiply it (hence 0 = shadowed, 1 = no shadow).

Yes. Only the ground.

Replace the “offensive” line with a hard-coded value such as 1.0.

L. Spiro

##### Share on other sites
Replace the “offensive” line with a hard-coded value such as 1.0.

Ah, It seems to work this way.

When replacing the line with shadowDistance = 5.0, I end up with this result:

I guess this means that the algorithm is correct, just that the shadow map really isn't getting sent in properly. I will also change my variables like you suggested. And thank you for all your help ^^.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628373
• Total Posts
2982306

• 10
• 9
• 13
• 24
• 11