How to generate directional shadow map?

You are an experienced programmer and have a problem with the engine, shaders, or advanced effects? Here you'll get answers.
No questions about C++ programming or topics which are answered in the tutorials!
Post Reply
mant
Posts: 125
Joined: Sun Jan 27, 2013 3:38 pm

How to generate directional shadow map?

Post by mant »

I'm rendering shadow map for directional light and here are my steps, do I make any mistakes?
- Have a camera for light view (cam)
- Set cam's position: vec3(100, 100, 100)
- Set cam's target as light direction: vec3(1, -1, 0)
- Build projection matrix as:

Code: Select all

 
const auto fov = 90.f * math::pi<float>() / 180.f;
mat.buildProjectionMatrixOrthoLH(fov, fov, 10, 100);
cam->setProjectionMatrix(mat, true);
 
- Set cam as the active camera of scene
- Set material of all nodes to a custom vertex/pixel shader pair to output depth.
- Render the scene to a texture

Vertex shader:

Code: Select all

 
uniform mat4 worldViewProjMat;
 
in vec3 in_vertex;
 
void main() {
  vec4 vert = vec4(in_vertex, 1.0);
  gl_Position = worldViewProjMat * vert;
}
 
worldViewProjMat is computed as:

Code: Select all

 
      auto worldMat = services->getVideoDriver()->getTransform(irr::video::ETS_WORLD);
      auto viewMat = services->getVideoDriver()->getTransform(irr::video::ETS_VIEW);
      auto projMat = services->getVideoDriver()->getTransform(irr::video::ETS_PROJECTION);
 
      auto worldViewProj = projMat * viewMat * worldMat;
 
      services->setVertexShaderConstant("worldViewProjMat", worldViewProj.pointer(), 16);
 
Pixel shader:

Code: Select all

 
out vec2 out_depth;
 
void main() {
  float depth = gl_FragCoord.z;
  out_depth = vec2(depth, depth * depth);
}
 
devsh
Competition winner
Posts: 2057
Joined: Tue Dec 09, 2008 6:00 pm
Location: UK
Contact:

Re: How to generate directional shadow map?

Post by devsh »

:facepalm:

FOV does not apply to Orthogonal projection!

Look at what the parameters are called, width and height of view volume, they are in your world-space units!
Also if I remember correctly for the IVideoDRiver transformations to change ICameraSceneNode::render() needs to be called on the camera.

Futhermore, you need to show HOW you are doing the shadow comparison.

The biggest issue however is

Code: Select all

 
float depth = gl_FragCoord.z;
 out_depth = vec2(depth, depth * depth);
 
From what I see what you're doing is VSM, and VSM needs LINEAR DEPTH (will be an issue for your non-directional shadows).
So go output scaled `(worldViewMat[0].z*vert.x+worldViewMat[1].z*vert.y+worldViewMat[2].z*vert.z+worldViewMat[3].z)` (or gl_Position.z or .w depending on light-type) into a varying and use that as `depth` in the pixel shader.
mant
Posts: 125
Joined: Sun Jan 27, 2013 3:38 pm

Re: How to generate directional shadow map?

Post by mant »

Thank you for replying.

I've just watched this video: https://www.youtube.com/watch?v=o6zDfDkOFIc

And see that I need a shadow box that moves with the camera, then my shadow map should be projected from the view of that shadow box.

Is it the view-space projection that you're implying with this sentence?
Look at what the parameters are called, width and height of view volume, they are in your world-space units!
Post Reply