Reputation: 116
I'm trying to implement shadow maps into my 3D world I created with openGL. I want to be able to move around the map and the shadow to follow as I move, so I needed a light Projection matrix that take into account my world view frustrum.
glm::mat4 lightProjectionMatrix = glm::ortho<float>(camera->_width * -0.5f, camera->_width * 0.5f,
camera->_height * -0.5f, camera->_height * 0.5f,
camera->_deep * -0.5f, camera->_deep * 0.5f);
glm::mat4 lightViewMatrix = glm::lookAt(camera->_centroid, camera->_centroid + glm::vec3(-1, -1, 0) , glm::vec3(0, 1, 0));
glm::mat4 lightModelMatrix = glm::mat4(1.0);
glm::mat4 lightMvp = depthProjectionMatrix * depthViewMatrix * depthModelMatrix;
The width, height, deep and centroid variables are from a cuboid of the orthographic projection for the light. To have it I used my world camera frustrum corners, rotated them into light space to do my calculation. Once I got the centroid and dimension of the cuboid into light space I convert them back into world space.
And this is my world projection matrix
_projection = glm::perspective(glm::radians(_fov), _screenRatio, _near, _far);
_projection = glm::scale(_projection, glm::vec3(-1, 1, 1));
_view = glm::lookAt(_cameraPos, _cameraPos + _dirLook, _cameraUp);
_mvp = _projection * _view;
the scale is to have a left handed world axis.
Now that I have all that I should be able to have a shadow texture with the positions as follow :
gl_Position = mvp * aPos;
shadowCoord = lightMvp * gl_Position;
but, my shadow aren't appearing. So I printed out some test case to see whats wrong :
auto pos = glm::vec3(50, 50, 300);
auto worldPos = _mvp * glm::vec4(pos, 1);
auto Light = lightMvp * glm::vec4(pos, 1);
auto worldLight = lightMvp * worldPos;
auto worldViewLight = lightMvp * _view * glm::vec4(pos, 1);
std::cout << "-----------" << std::endl;
std::cout << "worldPos = " << worldPos.x << " " << worldPos.y << " " << worldPos.z << std::endl;
std::cout << "Light = " << Light.x << " " << Light.y << " " << Light.z << std::endl;
std::cout << "worldLight = " << worldLight.x << " " << worldLight.y << " " << worldLight.z << std::endl;
std::cout << "worldViewLight = " << worldViewLight.x << " " << worldViewLight.y << " " << worldViewLight.z << std::endl;
worldPos = -194.856 -346.41 302.806
Light = 0.621941 0 0.177444
worldLight = 268.828 -0.0950791 67.447
worldViewLight = 1.15693 -0.250944 0.221805
And here are the results. when I multiply by light and world matrix I don't have values clamp between 0 and 1. And this is what I should have.
Note that my terrain is properly rendering and shadows appear when I don't multiply them by world space because they are clamp between 0 and 1.
So I don't understand why my world matrix breaks that.
Any ideas or advice?
Upvotes: 0
Views: 416
Reputation: 8283
When you transform to your light-space, you used an already transformed position. Instead, you should use the original vertex location for both the cam and the light transformation:
gl_Position = mvp * aPos;
shadowCoord = lightMvp * aPos; // DO NOT USE gl_Position;
Further things to note:
depth
and light
prefixes. Copy N Paste error?Upvotes: 1