Shadow acne on Nvidia graphics card
我和一个合作伙伴正在OpenGL中进行一个小型演示。我们正在做简单的阴影贴图。他使用ATI和Intel HD显示卡4000,一切正常。尽管我们使用相同的代码,但我使用GTX 560 TI并获得暗疮痤疮。
当我移动时,整个阴影都在闪烁。要设置帧缓冲区的深度缓冲区,请执行以下操作:
1 2 3 4 5 6 7 8 9 10 11 12 | glBindTexture(GL_TEXTURE_2D,_t_depth->name()); glTexImage2D( GL_TEXTURE_2D,0, GL_DEPTH_COMPONENT32, width,height, 0, GL_DEPTH_COMPONENT, GL_FLOAT,0); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D,0); glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,_t_depth->name(),0); |
顶点着色器的相关部分是:
1 2 3 4 5 | uniform mat4 u_lightspace_MVP; layout(location=0) in vec3 v_position; ... vec4 shadowcoord_x=u_lightspace_MVP*vec4(v_position,1.0); shadowcoord_x/=shadowcoord_x.w; |
片段着色器的相关部分是:
1 | if (texture(s_shadowMap,shadowcoord_x.xy).r>shadowcoord_x.z-0.0001) |
我尝试了不同的偏压值,但它不会影响粉刺或根本没有阴影。我还尝试将sampler2DShadow与textureProj()和texture()一起用作查找功能。似乎没有任何作用。这个问题不仅影响阴影,还影响使用阴影贴图的体积照明效果。
另一方面,在我的Nvidia上,使用gl_ClipDistance进行剪裁效果很好,但在他的图形卡上却不能。
经过进一步的反复试验,我终于摆脱了粉刺。我唯一要做的就是将阴影贴图的精度从32位减半到16位。初始化现在看起来像这样:
1 2 3 4 5 6 7 8 9 10 11 12 | glBindTexture(GL_TEXTURE_2D,_t_depth->name()); glTexImage2D( GL_TEXTURE_2D,0, GL_DEPTH_COMPONENT16, width,height, 0, GL_DEPTH_COMPONENT, GL_FLOAT,0); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE); glBindTexture(GL_TEXTURE_2D,0); glFramebufferTexture(GL_FRAMEBUFFER,GL_DEPTH_ATTACHMENT,_t_depth->name(),0); |
现在,我还在片段着色器中使用sampler2DShadow和textureProj()进行深度测试,并且一切正常。
仍然我很好奇为什么它不能在我的Nvidia上使用ATI并不能与32位一起使用。