Cleaning glsl sampler2Shadow and shadow2D

Brief information about where I am (to make sure that we are on the same page, and to check if I am absent / assume something stupid):

  • Purpose: I want to make my scene shadows using deferred lighting and shadowmaps.
  • Fight: search for clear and consistent documentation on how to use shadow2D and sampler2DShadow.

Here is what I am doing now:

In the fragment shader of my final rendering (the one that actually calculates the final fragment values) I have the MVP matrices from the passage from an easy point of view, the depth texture from this passage (also called the "shadow map" "), and the position / normal / color textures from my geometric buffer.

From what I understand, I need to find that the UV shadow map corresponds to the position of the current fragment. I do it as follows:

//Bring position value at fragment (in world space) to screen space from lights POV vec4 UVinShadowMap = (lightProjMat * lightViewMat * vec4(texture(pos_tex, UV).xyz,1.0)).xy; //Convert screen space to 'texture space' (from -1to1 to 0to1) UVinShadowMap = (UVinShadowMap+1)/2; 

Now that I have this UV, I can get the missing โ€œdepthโ€ from the light wave with

 float depFromLightPOV = texture2D(shadowMap, UVinShadowMap).r; 

and compare this with the distance between the position on the current fragment and the light:

 float actualDistance = distance(texture2D(pos_tex, UV).xyz, lightPos); 

The problem arises because the "depth" is stored in the values โ€‹โ€‹0-1, and the actual distance is in world coordinates. I tried to do this conversion manually, but could not get it to work. And on an internet search, it looks like I MUST do this with sampler2DShadow ...


So here is my question (s):

What changes do I need to make to use shadow2D instead? What does shadow2D do? Is this more or less the texture of automatic conversion from depth to world? Can I use the same depth texture? Or do I need to make the depth texture another way? What should I pass to shadow2D? I want to check the position in the world of fragment space? Or the same UV as before?

If all of these questions can be answered on a simple documentation page, I would like someone to just post this. But I swear I was looking for a watch and can't find anything that just says what happens to shadow2D!

Thanks!

+7
opengl glsl shadow-mapping
source share
1 answer

First, which version of GLSL are you using?

Starting with GLSL 1.30, there is no special texture search function (name anyway) for use with sampler2DShadow . GLSL 1.30+ uses a bunch of texture (...) overloads, which are selected depending on the type of sampler transferred and the size of the coordinates.

Secondly, if you use sampler2DShadow , you need to do two things differently:

  • Texture comparison should be enabled or you will get undefined results

    • GL_TEXTURE_COMPARE_MODE = GL_COMPARE_REF_TO_TEXTUREโ€‹

  • The coordinates that you switch to texture (...) are 3D instead of 2D. The new 3rd coordinate is the depth value that you are going to compare.

Finally, you should understand what texture (...) returns when using sampler2DShadow :

If this comparison passes, texture (...) will return 1.0 ; if it does not pass, it will return 0.0 . If you use the GL_LINEAR texture filter on your depth texture, then texture (...) will perform 4 depth comparisons using the 4 closest depth values โ€‹โ€‹in your depth texture and return a value somewhere between 1.0 and 0.0 to give an idea of โ€‹โ€‹the amount Missed / failed samples.

This is the right way to do hardware smoothing of shadow maps. If you tried to use the usual sampler2D with GL_LINEAR and implement the depth test yourself, you will get a single averaged depth back and the result of logical passing / failure instead of the behavior described above for sampler2DShadow .


As for getting the depth value for checking from a position in world space, you are on the right track (although you have forgotten the promising separation).

To create depth from a position in world space, three things must be done:

  • Multiply the position of world space by your (light) projection and display matrices
  • Divide the resulting coordinate by its component W
  • Scale and bias of the result (which is in the range [-1,1]) in the range [0,1]

The last step assumes that you are using the default depth range ... if you did not glDepthRange (...) then this will work.

The final result of step 3 serves both the depth value ( R ) and the texture coordinates ( ST ) to find in your depth map. This allows you to pass this value directly to texture (...) . Recall that the first 2 components of the texture coordinates are always the same, and the third is the depth value for verification.

+34
source share

All Articles