2016-07-28 136 views
0

我在GeForce GTX 750下使用OpenGL 4.3创建Shadow Map。现在基本效果如下图所示,似乎是正确的: enter image description here 要擦除块效应,我试着在着色器中手动执行2×2 PCF。它导致以下结果,这似乎也是正确的: enter image description here 对于加速,我想使用图形卡提供的好处,它提供了一次获取比较结果的线性过滤器。但效果与上述不同。 它更像是OpenGL的过滤阴影的渲染线,但在阴影贴图没有过滤器: enter image description here 下面是我如何做硬件PCF: 我注意到两个基本的东西,在做为了使用硬件PCF,它们是:使用OpenGL实现Shadow Map硬件PCF

  1. 使用shadow式采样器,这在我的情况下,是samplerCubeShadow(我使用一个立方体贴图类型,因为我试图创建一个点光源场景) 。
  2. 设置的比较模式和过滤型,这在我的情况下,通过下面的代码完成:

    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功能,只返回比较结果而不是做过滤,并给出了确切的结果如图2号图片。但是这没有自动过滤程序,显然它不是硬件PCF的完整版本。

回答

2

为了消除块效应,我试着在着色器中手动执行2×2的PCF。它导致以下结果,这似乎也是正确的:

OpenGL规范并未规定在线性内插深度比较时要使用的特定算法。然而,它通常描述为:

这样做的细节是依赖于实现的,但应r 在范围内的值[0,1]成比例的比较 通过或失败的次数。

这不是非常受限制,它肯定不需要输出,你看到“正确”。

事实上,actual PCF与您建议的要求有很大不同。你似乎想要的东西仍然非常麻烦。它只是不是二进制块。您的算法没有在比较结果之间进行线性插值;你只是做了4次最近的比较,并将它们平均在一起。

NVIDIA正在给你的是什么PCD实际上是假设看起来像这样:在比较结果之间的线性插值,基于你要采样的点。

因此,您的期望是错误的,而不是NVIDIA。

+0

所以,您的意思是,通过对比较结果进行平均,我不会执行NVIDIA执行的“线性插值” , 对?我检查了之前提供的材料,但没有说明如何完成这种插值。你能告诉我更多关于这方面的细节吗?谢谢。 – Narusaki

+1

@Narusaki:它是线性插值。它的工作原理与非比较情况相同,只是它对后比较值进行插值。 –

+1

哦,我想我明白了你的意思:线性插值应该使用从“中心坐标”到四个“角坐标”的距离作为“权重”,而不仅仅是对“角坐标”上的四个值进行平均,这种情况下的重量是0.25。那是对的吗? – Narusaki

0

通过@Nicol的回答,我想我误解了插值的含义。以下是我实现的着色器级插值,它看起来与问题中的第二张图片完全相同: enter image description here