Shadows mapping doesnt works as expected

Hello everyone! :slightly_smiling_face::victory_hand:

I have a really annoying problem :sweat_smile:

I wanted to made dropped shadows in the game :slightly_smiling_face:. During my searching I have know that it calls “Shadow Mapping” :grin:

I spend a lot of time on implementation this, and everything that I got is:

I want to ask you to help me to implement dropping shadows to the game :slightly_smiling_face:

Here’s the source code of this project :backhand_index_pointing_right: xolatgames/Dima-wants-crisps: Just a simple game where Dima can stands 🧍‍♂️, jumps, and walks 🏃‍♂️ - Codeberg.org

You don’t need to touch all of that :slightly_smiling_face:. Let me to explain you where’s the all that you needed :grin:

There’s the script that makes framebuffers for depth-testing :slightly_smiling_face::backhand_index_pointing_right: +o objects/info/packs +o info/refs.

There’s the place where locates the shaders those uses for depth-testing :slightly_smiling_face::backhand_index_pointing_right: Tree copies for relevant files (see gitattributes(5)). E.g.

They calls depth_shader.vert and depth_shader.frag

Also, there are the shaders those uses when the calculation shadows is finished, for rendering the level. And those uses the rendered framebuffer for they can take a decision, does here should be an obscuring place :slightly_smiling_face:

They calls diffuse.vert and diffuse.frag

Also, there’s the C++ script for rendering level by itself :backhand_index_pointing_right: Time, reducing the time zone ("author-tz"); similarly for.

But it’s not all that I wanted to tell you!

I also have not so much good experiment with the current version of the source code.

So, listen!

There’s game.cpp script :backhand_index_pointing_right: [--delta-base-offset] [--non-empty] [--local] [--incremental] [--window=<n>] [--depth=<n>] [--revs [--unpacked .

When I add glUseProgram(depth_shader_program); to the 185th line for it seems so there:

...

case Stage::LEVEL: {
	
	...
	
	level.RenderDepthBuffer(depth_shader_program);
	glViewport(0, 0, buffer_scale.x, buffer_scale.y);
	
	glm::mat4 vp = level.GetCameraMatrix();
	
	sky.Draw(vp);
	glUseProgram(depth_shader_program);
	level.Draw();
	
} break;

...

Then comment all the lines between 156th line and 163th line, except 160th line, and uncomment 166th line in level.cpp script for this part of this script seems so:

...

void Level::Draw() {
	/* shadow_map.BindTextureMap(diffuse_program);
	
	glUseProgram(diffuse_program); */
	
	UpdateVPMatrix();
	/* UpdateLightSpaceMatrix();
	
	RenderScene(); */
	
	// Uncomment this, if you want to see the depth map texture
	shadow_map.DrawPreview(twod_program);
	
	gui.Draw();
}

...

My game start looks so:

So, I have the one question :thinking:, and also want for you pay attention on these lines in level.cpp (between the 257th and 269th lines) :slightly_smiling_face::

...

void Level::UpdateLightSpaceMatrix() {
	glm::mat4 dir_light_m = dir_light.GetMatrix();
	light_space_matrix_id = glGetUniformLocation(diffuse_program, "lightSpaceMatrix");
	glUniformMatrix4fv(light_space_matrix_id, 1, GL_FALSE, glm::value_ptr(dir_light_m));
}

void Level::UpdateVPMatrix() {
	// A little trick for viewing the direction light projection ;P
	// glm::mat4 camera_vp = dir_light.GetMatrix();
	glm::mat4 camera_vp = GetCameraMatrix();
	vp_id = glGetUniformLocation(diffuse_program, "vp");
	glUniformMatrix4fv(vp_id, 1, GL_FALSE, glm::value_ptr(camera_vp));
}

...

And also pay attention on these lines (between 144th and 153th lines) in level.cpp where shadow_map.cpp start its working :slightly_smiling_face::

...

void Level::RenderDepthBuffer(GLuint depth_shader_program) {
	glUseProgram(depth_shader_program);
	UpdateLightSpaceMatrix();
	
	shadow_map.StartMapping();
	
	RenderScene();
	
	shadow_map.EndMapping();
}

...

There’s the place where the framebuffer renders everything that it needed for calculation the depth map :backhand_index_pointing_up:

And if we touch something in these lines at this moment:

...

void Level::Draw() {
	/* shadow_map.BindTextureMap(diffuse_program);
	
	glUseProgram(diffuse_program); */
	
	UpdateVPMatrix();
	/* UpdateLightSpaceMatrix();
	
	RenderScene(); */
	
	// Uncomment this, if you want to see the depth map texture
	shadow_map.DrawPreview(twod_program);
	
	gui.Draw();
}

...

For example, even UpdateVPMatrix();, everything may stop its working :slightly_smiling_face:. And then we got a black screen :sweat_smile:

So, my question is: Does the framebuffer just must to hold everything that it rendered between shadow_map.StartMapping(); and shadow_map.EndMapping();, and just be untouchable after that? :thinking: If it so… Why when I commend UpdateVPMatrix(); everything stop its working? :face_with_raised_eyebrow:

But, also, everything stop its working when I switches to glUseProgram(diffuse_program); at this time:

...

void Level::Draw() {
	// shadow_map.BindTextureMap(diffuse_program);
	
	glUseProgram(diffuse_program); // Uncommention of this at this time also breaks everything
	
	UpdateVPMatrix();
	/* UpdateLightSpaceMatrix();
	
	RenderScene(); */
	
	// Uncomment this, if you want to see the depth map texture
	shadow_map.DrawPreview(twod_program);
	
	gui.Draw();
}

...

So, please help me to fix the shadows in my game :wrench::slightly_smiling_face:

Thanks to everyone for your attention! :grin:

Sorry about this, but this is my inattention :slightly_smiling_face:

But here’s almostly a morning :yawning_face::slightly_smiling_face:

I will try to tell you about my successes tomorrow :wink:

Now I want to tell you where are the problems was be :slightly_smiling_face:

The problems was be in level.cpp script between 257th and 261th lines:

...

void Level::UpdateLightSpaceMatrix() {
	glm::mat4 dir_light_m = dir_light.GetMatrix();
	light_space_matrix_id = glGetUniformLocation(diffuse_program, "lightSpaceMatrix");
	glUniformMatrix4fv(light_space_matrix_id, 1, GL_FALSE, glm::value_ptr(dir_light_m));
}

...

And between 271th and 277th lines:

...

void Level::RenderScene() {
	player.Draw(diffuse_program);
	
	for (Obstacle* obstacle : obstacles) {
		obstacle->Draw(diffuse_program);
	}
}

...

I was don’t drop lightSpaceMatrix to the GLSL shaders where at the current state depth_shader_program uses :sweat_smile:

And this cause unrendered picture in my shadows mapping :slightly_smiling_face:

For fixing this I changed my UpdateLightSpaceMatrix function, so it looks so now:

void Level::UpdateLightSpaceMatrix(GLuint program) {
	glm::mat4 dir_light_m = dir_light.GetMatrix();
	light_space_matrix_id = glGetUniformLocation(program, "lightSpaceMatrix");
	glUniformMatrix4fv(light_space_matrix_id, 1, GL_FALSE, glm::value_ptr(dir_light_m));
}

And, also, m matrices wasn’t be dropped to depth_shader_program. But they was be needed for the calculation of models spaces. And I also was need to fix this in RenderScene function:

void Level::RenderScene(GLuint program) {
	player.Draw(program);
	
	for (Obstacle* obstacle : obstacles) {
		obstacle->Draw(program);
	}
}

And, for everything start its working, I also was need to change a couple of the functions in level.cpp between 144th and 169th lines:

...

// Old version
/* void Level::RenderDepthBuffer(GLuint depth_shader_program) {
	glUseProgram(depth_shader_program);
	UpdateLightSpaceMatrix();
	
	shadow_map.StartMapping();
	
	RenderScene();
	
	shadow_map.EndMapping();
}

void Level::Draw() {
	shadow_map.BindTextureMap(diffuse_program);
	
	glUseProgram(diffuse_program);
	
	UpdateVPMatrix();
	UpdateLightSpaceMatrix();
	
	RenderScene();
	
	// Uncomment this, if you want to see the depth map texture
	// shadow_map.DrawPreview(twod_program);
	
	gui.Draw();
} */

// New version
void Level::RenderDepthBuffer(GLuint depth_shader_program) {
	glUseProgram(depth_shader_program);
	UpdateLightSpaceMatrix(depth_shader_program);
	
	shadow_map.StartMapping();
	
	RenderScene(depth_shader_program);
	
	shadow_map.EndMapping();
}

void Level::Draw() {
	shadow_map.BindTextureMap(diffuse_program);
	
	glUseProgram(diffuse_program);
	
	UpdateVPMatrix();
	UpdateLightSpaceMatrix(diffuse_program);
	
	RenderScene(diffuse_program);
	
	// Uncomment this, if you want to see the depth map texture
	// shadow_map.DrawPreview(twod_program);
	
	gui.Draw();
}

...

And now :slightly_smiling_face::

...

void Level::Draw() {
	shadow_map.BindTextureMap(diffuse_program);
	
	glUseProgram(diffuse_program);
	
	UpdateVPMatrix();
	UpdateLightSpaceMatrix(diffuse_program);
	
	RenderScene(diffuse_program);
	
	// v
	shadow_map.DrawPreview(twod_program); // <- When I uncomment this line
	// ^
	
	gui.Draw();
}

...

I can see that my framebuffer works correctly :grin::

Here’s some thing that I have know right now :thinking:: Source files in C++ :slightly_smiling_face: those, for example, ends with “.cpp”, “.hpp”, etc, calls not scripts :slightly_smiling_face:, but “Source files” :sweat_smile:

And I didn’t know that calling them as “scripts” also :thinking: isn’t a correct way :slightly_smiling_face:

Nice catch, passing the correct shader program to the matrix update fixed the shadow rendering issue. Also good to know the framebuffer was working correctly after the changes. And yes, “source files” is the better term for .cpp and .hpp files

Shadow mapping can be tricky because the depth pass and normal render pass need different shaders, matrices, viewports, and framebuffer state. I’d check the OpenGL state between those two passes first, especially , the viewport, and the light-space matrix.

Yeap! :slightly_smiling_face: I will be more attentive at these details in the next time :grin:

Will show you the results soon :slightly_smiling_face:. When I published a new video on my PeerTube channel about this game - I’ll also put here the link to this video :wink:

Here’s this video :backhand_index_pointing_down:

For who ones who have an interest - I wish a nice watching! :smiling_face_with_sunglasses::popcorn:

But there’s not only about “Dima wants crisps :french_fries:”, if be honest :thinking: