我在一些变体中实现了对 MSAA 的支持:
它可以使用基于上下文(通过在设置上下文时调用 wglChoosePixelFormatARB 并将相应的参数列表传递给它)或通过启用 MSAA 渲染到 FBO(创建一个带有颜色和深度渲染缓冲区附件的多采样 FBO,以及另一个带有颜色附件的 FBO用于解决),并且抗锯齿似乎在整体上起作用。
然而,当我启用抗锯齿时,我发现了一些似乎与镜面反射照明有关的伪影。这对于基于上下文的 CSAA 来说是最差的,对于基于上下文的 MSAA 来说非常糟糕,但是当我在渲染到我的 FBO 时使用 MSAA 时会好得多。
对于我用于测试的其中一种飞机模型,它非常引人注目,尤其是在发动机气缸和一些“电线”周围(它们实际上不是线,而是细气缸):
正如您在图像上看到的,当我关闭镜面反射光时,问题几乎消失了,但我不太确定是什么原因造成的。
上面的图像使用这个着色器代码来计算镜面反射(在所有灯光的循环内):
if( matShininess > 0.0 )
{
vec3 reflectionCamSpace = reflect(-lightDirectionCamSpace, faceNormal);
vec3 surfToViewerCamSpace = normalize (-vertPositionCamSpace);
float dotSpecular = max( 0.0, dot (reflectionCamSpace, surfToViewerCamSpace) );
float specularFactor = pow( dotSpecular, matShininess );
specularTerm += vec3(lgt.specular * specularFactor);
}
不同的照明模型之间似乎也存在很大差异:
左侧使用上述代码进行镜面高光,而右侧使用此代码(再次在主光循环内,迭代所有灯光)
if( matShininess > 0.0 )
{
vec3 surfToViewerCamSpace = normalize (-vertPositionCamSpace);
vec3 halfAngle = normalize(lightDirectionCamSpace + surfToViewerCamSpace);
float specularFactor = dot(faceNormal, halfAngle);
specularFactor = clamp(specularFactor, 0, 1);
specularFactor = lightDot != 0.0 ? specularFactor : 0.0;
specularFactor = pow(specularFactor, matShininess);
specularTerm += vec3(lgt.specular * specularFactor);
}
所以我想知道为什么在使用基于 FBO 的 MSAA 和基于上下文的 MSAA 时会有如此大的差异。还有我做错了什么我的镜面高光首先造成了问题?
编辑:按照下面帖子的要求,我还添加了一个测试,用于通过上下文和 FBO 比较 16xQ CSAA 的结果(对于 FBO,我只是使用 RenderbufferStorageMultisampleCoverageNV 而不是 glRenderbufferStorageMultisample)。同样,FBO 结果似乎更好(但仍不令人信服):