I am attempting to implement shadow maps.

I am first going to implement spotlights over directional lights (I am aware this is harder).

Since I was already rendering the geometry, my attempt was to recycle my old shaders and modify them to make shaders to create the depth maps.

This created the following vertex shader:

#version 450

layout(location = 0) in vec3 position; //(x,y,z) coordinates of a vertex

layout(std430, binding = 3) buffer data_buffer
    vec4 cubes_info[];//first 3 values are position of object 

uniform mat4 view = mat4(1); //Camera orientation and position
uniform mat4 proj = mat4(1); //The projection parameters (FOV, viewport dimensions)

void main()
    gl_Position = proj*view*(vec4(position, 1.0) + vec4(vec3(cubes_info[gl_InstanceID]),0));

And fragment shader:

#version 450

layout(location = 0) out float fragmentdepth;

void main()
    fragmentdepth = gl_FragCoord.z;

As you can see, both shaders are pretty basic, they are a little more complex than they would otherwise be since they are using instancing, but overall they are simple.

However the output of these shaders is:

Screenshot of voxel terrain, in full 0xFF0000 red

Where the original image is:

Screenshot of grey-white voxel terrain, with lihting applied

As you can see, the depth is being lost.

I think this is because my perspective, projection and model matrices are identical for both shaders.

In other words, I think that the camera I use for rendering the second image does not store the depth information. I wanted to know how can you generate a similar projection matrix to store the depth?

  • \$\begingroup\$ If your normal camera/projection transformations weren't passing depth through properly, how is it that your second image appears to be correctly z-buffered, with no places where a faraway cube draws over a nearby one due to identical depth results from the matrix? To me, this looks like your matrix is probably fine, and you might just need to tune how you're reading & remapping the depth value from the transformed result. \$\endgroup\$
    – DMGregory
    Feb 14 '18 at 11:28

One of the things you need to understand that the red component is actually visually correct. The Z Depth is being embedded in values close to 1.

If you want to just see a colour change to see the depth values more visually, you can either shorten the back plane to allow a greater range of values (not tracking close 1.0f).

I usually use the trick of depth = saturate((depth - 0.95f) * 20.0f);

What this does is stretch that part of the z buffer out (when im replaying the buffer back through a Pixel shader).

You may find what you have is working perfectly fine. Z Depth is not written in a linear fashion btw most of the time.

Sample of what you should see in your shadow buffer

Shadow buffer content vs backbuffer

  • \$\begingroup\$ Your assumption is wrong, the values are not "close" to 1, they are all exactly 1. Dividing by any scalar just results in a different shade of grey, not a variation in color as you would expect from a depth map. \$\endgroup\$
    – Makogan
    Feb 14 '18 at 4:05
  • \$\begingroup\$ refer to the additional picture \$\endgroup\$
    – ErnieDingo
    Feb 14 '18 at 8:17
  • 2
    \$\begingroup\$ @Makogan You're under the assumption that gl_FragCoord.z is linear. It's not. code.i-harness.com/en/q/76ae79 \$\endgroup\$
    – Sidar
    Feb 14 '18 at 10:29

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.