Search code examples
glslesshadow-mappingwebgl2

WebGL2 - Can I query a shadowmap cubemap with non world position?


I'm trying to implement shadow maps for point lights using Webgl2. To do so, I use a cubemap of depth buffers to which I render 6 axis aligned views from the light position.

In the fragment shader I use to render lighting, I query this cubemap using these lines:

vec3 lightToPos = lightPos-fragPos;
float closestDepth = texture(shadowMap, lightToPos).r;

Note that lightPos and fragPos are in 'view' referential, that is: viewMat * worldMat * objPos. In the tutorial I'm following this is supposed to be in World Position (http://ogldev.atspace.co.uk/www/tutorial43/tutorial43.html). Now, I don't see a reason why my way of doing it wouldn't work because the difference of two positions should be the same regardless of the point of view their coordinates are expressed in, right? The results I'm getting are not what I'm expecting, everything is in the shadow. I have probably made a mistake elsewhere but I would like to be sure I understood how that works and that the mistake is not from here.


Solution

  • the difference of two positions should be the same regardless of the point of view their coordinates are expressed in, right?

    No, they're not.

    Consider a world where the light is straight above the origin of the world, and "above" means in the +Y direction. So that's the direction the shadow map was generated from. And it was generated from world-space.

    Now, consider the camera at the origin of the world. It's looking down the -Z axis, with +Y in pointing straight up. In this case, there is no orientation difference between camera space and world space. Therefore, in both cases, the light direction is (0, 1, 0).

    But what happens if you rotate the camera 90 degrees around its viewing axis? Well, the camera is lying on its side, relative to the world. That means the light direction is either (1, 0, 0) or (-1, 0, 0), depending on which way you rotated. And that direction is different from the world space direction, which is still (0, 1, 0).

    Yes, the light did not move, relative to the world. But the camera did. Therefore, the value of the camera-space light direction is different from what its value would be for the world-space light direction.

    If both the light position and the fragment position truly are in camera space, then subtracting them will give the direction to the light in camera space. If the shadow map was indeed built in world space, this direction will be utterly useless.