1

I've gotten shadows working properly for my Directional Lights, but I'm a little stumped when it comes to Point Lights. My idea is to use a cube map to render the depth from all six sides surrounding the light. So far, that's all working and good. I have verified this step by rendering each face of my cube to a 2D image, and it appears to be correct.

Now I'm trying to get the shadows to show up in the world. To do so, I am using GLSL's samplerCubeShadow data type. With it, I do:

vec3 lightToFrag = light.position - fragPos
float lenLightToFrag = length(lightToFrag)
vec3 normLightToFrag = normalize(lightToFrag)
float shadow = texture(depthTexture, vec4(normLightToFrag, lightToFrag))

I've tried a number of configurations, and this always renders my scene in black. Any ideas? My fragPos is just the model matrix times the vertex position. Should I be applying the light's model-view matrix to it? Or, similarly, should I be applying the world's model-view matrix to the light? Any feedback is really appreciated!

recp
  • 383
  • 1
  • 2
  • 14
Matt Kae
  • 147
  • 5
  • 1
    Here your answer: https://stackoverflow.com/questions/10786951/omnidirectional-shadow-mapping-with-depth-cubemap/10789527#10789527 if you store depth values in cubemap you need to convert lightToFrag to depth value to compare – recp Feb 07 '18 at 11:16

1 Answers1

2

Assuming you are storing depth values in cubemap;

AFAIK cubemap is an AABB in world space, so you need to do calculations in world space. In your case light.position and fragPos must be in world space, or provide alternative variables/members if you use these names in view space in somewhere else e.g. per-fragment light calculations

Also you need to convert lightToFrag to depth value before pass to texture. This answer shows how to convert lightToFrag to depth value: Omnidirectional shadow mapping with depth cubemap

Here my implementation (I removed #ifdef SHAD_CUBE because others use same name):

uniform samplerCubeShadow uShadMap;
uniform vec2              uFarNear;

float depthValue(const in vec3 v) {
  vec3 absv = abs(v);
  float z   = max(absv.x, max(absv.y, absv.z));
  return uFarNear.x + uFarNear.y / z;
}

float shadowCoef() {
  vec3  L;
  float d;

  L = vPosWS - light.position_ws;
  d = depthValue(L);

  return texture(uShadMap, vec4(L, d));
}

This may require uniform model matrix if you only have ModelViewProjection (MVP)

Here how to calculate uNearFar at client side:

  float n, f, nfsub, nf[2];

  n = sm->near;
  f = sm->far;

  nfsub = f - n;
  nf[0] = (f + n) / nfsub * 0.5f + 0.5f;
  nf[1] =-(f * n) / nfsub;

  glUniform2f(gkUniformLoc(prog, "uFarNear"), nf[0], nf[1]);

this is just optimization but you don't have to use this and follow the link which I mentioned before.

You may need bias value, related answer uses bias but I'm not sure how to apply it to cubemap correctly. I'm not sure d -+ 0.0001 is correct way or not.

If you want to store world distances in cubemap then this tutorial seems god one: https://learnopengl.com/Advanced-Lighting/Shadows/Point-Shadows

recp
  • 383
  • 1
  • 2
  • 14
  • Sorry for the delayed response, but that was it! You saved me a ton of debugging, in the C++ code. I should've read up on it before hand. Anyways thanks for the references and everything! – Matt Kae Feb 11 '18 at 00:58