-1

I want to calculate the shadows of my pointlights with the following two passes:

First, I render the scene from pointlight's view into a cubemap into all six directions with the scene-objects' modelspace, the according viewmatrix for the cubemap's face and a projection matrix with 90 degree FOV. Then I store the distance in worldspace between the vertex and the lightposition (which is the camera's position, so just the length of the vertex rendered in worldspace). Is it right to store worldspace here?

The cubemap is a GL_DEPTH_COMPONENT typed texture. For directional and spotlights shadowing works quite well, but those are single 2D textures

This is the shader with which I try to store the distances:

VertexShader:

#version 330
layout(location = 0) in vec3 vertexPosition;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;

out vec4 fragmentPosition_ws;

void main(){
    gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(vertexPosition, 1.0);
    fragmentPosition_ws = modelMatrix * vec4(vertexPosition, 1.0);
}

FragmentShader:

#version 330

// Ouput data
layout(location = 0) out float fragmentdist;

in vec4 fragmentPosition_ws;

void main(){
    fragmentdist = length(fragmentPosition_ws.xyz);
}

In the second step, when rendering the lighting itself, I try to get those distance values like this:

float shadowFactor = 0.0;
vec3 fragmentToLightWS = lightPos_worldspace - fragmentPos_worldspace;

float distancerad = texture(shadowCubeMap, vec3(fragmentToLightWS)).x;

if(distancerad + 0.001 > length(fragmentToLightWS)){
    shadowFactor = 1.0;
}

Notes: shadowCubeMap is a sampler of type samplerCube

lightPos_worldspace is the lightposition in worldspace (lights are already in worldspace - no modelmatrix)

fragmentPos_worldspace is the fragmentposition in worldspace ( * modelmatrix)

The result is, that everything is lighted aka. not in shadow. I am sure, that rendering into shadowmap works. I tried several implementations of calculating the shadow and sometimes a saw something like shadows, that could be objects. BUT this was with NDC shadowdepths and not the distancemethod. So check this also for mistakes.

genpfault
  • 51,148
  • 11
  • 85
  • 139
  • No `viewMatrix` when rendering the depth values? How do you determine into which face of the cubemap the depth values go? Also, with a single export, `layout(location = 0)` is unnecessary because it's the default. – thokra Oct 30 '13 at 16:10
  • @thokra No, no viewmatrix for the distancevalues when writing to the texture. In code I select my face after binding the framebuffer with: glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, face, _cubeMap, 0); face is GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, where i goes from 0 to 5 – Frischer Hering Oct 30 '13 at 16:15
  • Multiplying with viewmatrix for the distancevalues doesnt work better. Still everything lit. And additionaly with the projectionmatrix, either. – Frischer Hering Oct 30 '13 at 16:17
  • Ehm, the distance from the light source is the depth. You still need to orient vertices properly so their distance after transformation to light-space is stored inside the correct face. Therefore, multiplication by the current light source's viewMatrix is necessary. – thokra Oct 30 '13 at 16:18
  • fragmentPosition_cs = viewMatrix * modelMatrix * vec4(vertexPosition, 1.0); doesnt work either. what about the calculation of the direction in the lighting shader? What view matrix shall I choose. There are six possible – Frischer Hering Oct 30 '13 at 16:20
  • Yes, that's correct. I suggest you normalize the depth values and render the depth maps to a quad you can inspect first. Make sure your depth buffers are actually rendered correctly. – thokra Oct 30 '13 at 16:21
  • So there is a problem when I store the distances in the texture? – Frischer Hering Oct 30 '13 at 16:22
  • 1
    Speaking of storing distances in the texture, you are wasting memory bandwidth by doing it this way. The better solution is to use a regular old depth cube map and then in your fragment shader resolve the comparison using something like `float VectorToDepthValue(vec3 Vec)` in [this question](http://stackoverflow.com/questions/13999830/pointers-on-modern-opengl-shadow-cubemapping?rq=1). This will get you better shadowmap throughput; added instructions to perform the comparison are preferable to increased memory bandwidth requirements, which shadows already significantly hog. – Andon M. Coleman Oct 30 '13 at 16:23
  • Yes. Usually comparisons are done in light-space, i.e. you transform vertices to light-space and then do the comparison of the transform distance to the light and the one stored in the depth buffer. – thokra Oct 30 '13 at 16:24
  • What matrices exactly do I use, when I transform my vertex into lightspace afterwards? – Frischer Hering Oct 30 '13 at 16:27
  • I just realized, when rendering the depth buffer, you apply light-space and clip-space transformations. However, you store world-space position named `fragmentPosition_ws`, which is complete nonsense. Also, this is only correct if the pointlight is at the origin. You need to be consistent with the spaces you use. You can use either world-space and light space, but you need to make sure you actually compare values from similar spaces. – thokra Oct 30 '13 at 16:27
  • The pointlight is at the origin due to it is the point from which the scene is rendered. Can you give me instruction how to do that with old shadowmaps and in worldspaces? Say I have the `float VectorToDepthValue(vec3 Vec)` method already with correct near and far values set – Frischer Hering Oct 30 '13 at 16:29
  • I do not know, what to do. – Frischer Hering Oct 30 '13 at 16:47
  • I just checked the shadowCubeMap and have to say, that it has rendered the shadows to it properly (well it is upside-down, but these is easy corrected and the shadows casted should be seen too). So what is wrong, is sampling FROM the cubemap. – Frischer Hering Oct 30 '13 at 16:59

1 Answers1

0

So, finally I made it. I got shadows :)

The solution: I used as suggested the old shadowmap technique with depthvalues. I sample from the cubemap still using the difference of light to vertex (both in worldspace) but I compare the value with the vertexToDepth() method from the other question mentioned.

Thanks for your help and clarifying points

The point is: Always be sure to compare the same values! When depthmap stores worldspace-depth, then also compare with such a value.