Cracks appear when using MipMap for variance shadow map to filter csm

Started by
0 comments, last by MJP 9 years, 6 months ago
I use OpenGL to implement a PSVSM,for a better filter,I use MipMap for the variance map.
glGenTextures(1,&VarTex);
glBindTexture(GL_TEXTURE_2D_ARRAY,VarTex);
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0,GL_RG32F,Resolution,Resolution,nSplits, 0,GL_RG, GL_FLOAT, 0);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER);
glTexParameteri(GL_TEXTURE_2D_ARRAY, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER);
glTexParameterfv(GL_TEXTURE_2D_ARRAY,GL_TEXTURE_BORDER_COLOR,borderColor);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,16);
I use glGenerateMipmap(GL_TEXTURE_2D_ARRAY); to generate the MipMap
[attachment=24354:map.JPG]
As you can see in the attach files,Cracks appear between each split frustum.But it only appears when i use MipMap.
I very want to know why it happen while using the MipMap.More importantly,HOW TO SOLVE IT!
This is the code of the shader:

#version 330
layout(location=0) out vec2 FragColor;
void main()
{float dep=gl_FragCoord.z;
FragColor.x=dep;
FragColor.y=dep*dep;
}
///////////////////////////////////////////////////////////////////////////

#version 330 core
#extension GL_EXT_texture_array:enable
layout(location = 0) out vec3 FragColor;
uniform mat4 BMVP[8];
uniform float dis[8];
uniform int nSplits;
in VS_OUT
{float factor;
vec4 V_WORLD;
}fs_in;
uniform sampler2DArray VarMap;
float UppderBound(vec2 Moments,float t)
{if(t<=Moments.x)return 1.0;
float var=Moments.y-(Moments.x*Moments.x);
var=max(var,0.0002);
float d=t-Moments.x;
return var/(var+d*d);
}
void main()
{float offset=-0.00001;
vec4 texCoord;
int index=nSplits-1;
for(int i=0;i<nSplits;i++)
if(gl_FragCoord.z<dis){index=i;break;}
texCoord=BMVP[index]*fs_in.V_WORLD;
vec2 uvs=texCoord.xy/texCoord.w;
float z=texCoord.z/texCoord.w;
FragColor=vec3(
UppderBound(
texture2DArray(VarMap,vec3(uvs,index)).rg
,z+offset));
}
Advertisement

Mipmaps are selected by automatically selected by computing the gradients of the texture coordinate across a 2x2 quad of pixels. Since you're doing cascade selection per-pixel, you can end up with 2 pixels within the same quad selecting different cascades. When this happens the texture coordinates will be in a different coordinate space, which will give you incorrect gradients (and thus incorrect mipmapping). To make this work you either need to guarantee that all pixels within a quad select the same cascade, or you need to calculate your gradients manually in a way that takes the cascades into account. Basically you want to compute your ddx/ddy of your position before applying the cascade matrix, then use that to reconstruct your neighboring positions. Then you can apply the selected cascade matrix to all 3 positions, and manually compute the gradients in shadow map UV space. Or altenatively if you re-arrange things so that you have 1 global shadow matrix with separate scale/offset for each cascade, you can do things more efficiently. This is the approach I used in my shadow map test framework.

This topic is closed to new replies.

Advertisement