Are soft shadows possible with point lights using cubemap (OpenGL / GLSL)?

I have coded a 3D application that controls the display of the drop shadow. To do this, I use the classic shadow rendering technique (I fill the depth texture in the first render pass, and in the second render pass I compare the distance from the light to the first occluder and the distance from the light to the vertex position to see if the fragment is in shadow or not).

Here is a screenshot (shadow shadow / 2D depth texture picture):

enter image description here

In this example I am using the PCF shadow rendering technology using the "textureProjOffset" function. Here is a code snippet from my fragment shader:

Sampler used:

sampler2DShadow Shadow2DSampler[MAX_LIGHTS_COUNT];


For HARD shadows:

shadowFactor = textureProj(Shadow2DSampler[idx], ShadowCoords[idx]);


For SOFT shadows PCF:

for (int idy = offset; idy >= -offset; idy--)
                for (int idx = -offset; idx <= offset; idx++)
                    shadowFactor += textureProjOffset(
                        Shadow2DSampler[idz], ShadowCoords[idz], ivec2(idx, idy)); 


I also managed the basic cubemap shadow mapping to control the omni-directional shadow mapping currently used for point lights. To do this in the first render pass, I use a geometry shader to send both the projection matrix and the view provided by 6 shadow fruits (all in ONE pass! This is different from the method of filling 6 separate textures with this time 6 display states) ...

Here is a screenshot (point light / cube texture depth mapping):

enter image description here

As you can see, this is only DIFFICULT shadow rendering. To restore the depth value encoded in the cube map, I have to use this time for the "texture" function (textureProj does not exist for "samplerCube" and "samplerCubeShadow"). Then I need to calculate the distance between the position of the light and the position of the vertices in world space and then convert it to clip space because the depth value contained in the texture is already in clip space.

Here's a snippet of code from the fragment shader to see the process:

Sampler used:

samplerCubeShadow ShadowCubeSampler[MAX_LIGHTS_COUNT];


For HARD shadows:

float ConvertDistToClipSpace(vec3 lightDir_ws)
    vec3 AbsVec = abs(lightDir_ws);
    float LocalZcomp = max(AbsVec.x, max(AbsVec.y, AbsVec.z));

    float NormZComp = (NearFar.y + NearFar.x)/(NearFar.y - NearFar.x)
        - (2.0f * NearFar.y * NearFar.x)/(LocalZcomp * NearFar.y - NearFar.x);

    return ((NormZComp + 1) * 0.5f);

float GetBiased_Cube_Hard_ShadowFactor(vec3 vertexPosition_ws, int idx)
    vec3 lightToVertexDir_ws = vertexPosition_ws -;
    float LightToVertexClipDist = ConvertDistToClipSpace(lightToVertexDir_ws);

    float LightToOccluderClipDist = texture(
        ShadowCubeSampler[idx], vec4(lightToVertexDir_ws, LightToVertexClipDist));

    if (LightToOccluderClipDist < LightToVertexClipDist)
        return (0.0f);
    return (1.0f);


And you know how about PCF SOFT shadows using cubemap? I am doing some research and there seems to be no function to restore the texture displacement as possible using simple 2D textures and using the "sampler2DShadow" keyword in the fragment shader. Am I wrong? (I hope so!).

I think I have a solution (unless of course it has a solution with cubemap):

Apparently, I will have to use 6 separate textures to restore the texture offset (so the "sampler2DShadow" array is 6, not "samplerCubeShadow"). So I will have an equally uniform 4x4 matrix array representing the world view in light space, as I did for point shadow mapping in my first case. And then I will use the "textureProjOffset" method for 6 textures.

So what do you think? Is it possible to use soft PCF shadows with cubemap or not? If not, is my solution correct? Can I use a function like textureProjOffset using 'samplerCube' or 'samplerCubeShadow'? Or is there an alternative?

Thank you for your help!


source to share

1 answer

The only thing I know to achieve soft PCF shadows for cubemaps is to request the texture multiple times with a slight offset. This method, for example, is described in this article article GPU Gems (12.4) .



All Articles