我在GeForce GTX 750下使用OpenGL 4.3来创建阴影贴图。现在,基本效果,如下所示,似乎是正确的: 为了消除块效应,我试图在着色器中手动执行2x2 PCF。它导致以下结果,这似乎也是正确的: 为了加速,我想使用图形卡提供的好处,它给出了比较结果的线性过滤器和一次获取。但效果与上述不同。 更像是OpenGL过滤阴影线性渲染,而不是阴影贴图上的滤镜: 下面是我如何做硬件PCF: 我注意到为了使用硬件PCF必须完成的基本两件事:
shadow
类型的采样器,在我的情况下,samplerCubeShadow
(我使用立方体贴图类型,因为我试图创建一个点光源场景)。 设置比较模式和过滤类型,在我的例子中,由以下代码完成:
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL);
之后,我在着色器中使用texture
这样的功能(我使用texture
而不是textureProj
的原因是因为后者似乎不支持立方体贴图阴影纹理,因为它需要vec5
类型,显然还不支持):
vec4 posInLight4D = positionsInLight / positionsInLight.w; // divided by the 4-th component)
vec3 texCoord = GetCubeMapTexCoord(posInLight4D.xy); // get the texture coordinate in cube map texture. This can be assumed correct
float lightness = texture(shadowMapHardware, vec4(texCoord, posInLight4D.z));
但不幸的是,这给出了第三张图片中显示的结果。
据我所知,通过设置比较模式和线性过滤器,显卡将进行比较附近的2x2区域和线性插值结果并通过texture
函数返回。我想我已经完成了所有必要的部分,但我仍然无法得到第二张图片中显示的确切结果。
任何人都可以给我任何关于我可能出错的地方的建议吗?非常感谢。
ps:有趣的是:我尝试了textureGather
函数,它只返回比较结果,但没有进行过滤,它给出了精确结果,如第二张图所示。但这缺乏自动过滤程序,显然它不是硬件PCF的完整版本。
答案 0 :(得分:2)
为了消除块状效果,我试图在着色器中手动执行2x2 PCF。它导致以下结果,这似乎也是正确的:
OpenGL规范没有规定线性插值深度比较时要使用的特定算法。但是,它通常将其描述为:
这个细节依赖于实现,但
r
应该 是[0,1]范围内的值,与比较次数成比例 传球或失败。
这不是很严格,它肯定不需要你认为“正确”的输出。
事实上,actual PCF与你想要的东西有很大的不同。你似乎想要的仍然是非常块状的;它只是不是二进制块。您的算法没有在比较结果之间进行线性插值;你刚刚进行了4次最近的比较并将它们平均化了。
NVIDIA给你的是PCD实际上假设的样子:比较结果之间的线性插值,基于你的采样点。
所以你的期望是错误的,而不是NVIDIA。
答案 1 :(得分:0)