0

我已经实现了延迟渲染,并尝试使用多重采样纹理进行抗锯齿。

我将场景渲染为具有多重采样纹理的 FBO,使用 glBlit 在第二个 FBO 中创建常规纹理,最后将纹理绑定到生成最终图像的光照着色器。

// draw to textures
mMultiGeometryFBO->bind();
glViewport(0,0,mWidth,mHeight);
glEnable(GL_DEPTH_TEST);
glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT );

// calling all modules to draw to FBO
for(auto r : mRenderer)
    r->renderMaterial(camera);

glBindFramebuffer(GL_READ_FRAMEBUFFER, mMultiGeometryFBO->fbo());
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mGeometryFBO->fbo());

glReadBuffer(GL_COLOR_ATTACHMENT0);
glDrawBuffer(GL_COLOR_ATTACHMENT0);
glBlitFramebuffer(0, 0, mWidth, mHeight,
                  0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_LINEAR);

glReadBuffer(GL_COLOR_ATTACHMENT1);
glDrawBuffer(GL_COLOR_ATTACHMENT1);
glBlitFramebuffer(0, 0, mWidth, mHeight,
                  0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);

glReadBuffer(GL_COLOR_ATTACHMENT2);
glDrawBuffer(GL_COLOR_ATTACHMENT2);
glBlitFramebuffer(0, 0, mWidth, mHeight,
                  0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_LINEAR);

// draw to screen
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClear(GL_DEPTH_BUFFER_BIT);

mSkybox->renderMaterial(camera);

mShader->use();
mShader->setTexture("tDiffuse", mDiffuseColor, 0);
mShader->setTexture("tNormal", mNormals, 1);
mShader->setTexture("tMaterial", mMaterialParams, 2);
mShader->setTexture("tDepth", mDepthBuffer, 3);
mShader->setTexture("tLights", mLightColor, 4);
mQuad->draw();

这会在地平线(几何体和天空盒之间)产生一条可见线。颜色是清晰的颜色。只有清除深度才能减少移动时的问题。在渲染几何之前将 SkyBox 渲染到 FBO 会产生不太明显的伪影,但线条仍然存在。

编辑:忘记图片 在此处输入图像描述

4

1 回答 1

1

从概念上讲,在光照通道之前解析多样本目标没有意义。您将得到的是 gbuffers 中的值将在对象的边缘进行平均。这对于法线方向尤其不利。想一想:如果您有一个像素包含 50% 的地平面和 50% 的天空,您将得到一个法线方向,即 (normal_ground + normal_sky)/2。这与使用原始法线计算每个部分的最终颜色并混合生成的颜色完全不同。

如果您想使用延迟渲染进行多重采样,则必须使用多重采样目标进行照明,并且必须启用每个样本着色并实际单独访问和点亮每个样本,并且仅将最终结果blit到非多重采样目标. 但是,这将非常昂贵。您尤其会失去多重采样与超级采样的好处。

我不知道是否有一些巧妙的技巧仍然可以以更有效的方式使用多重采样,但通常的方法是根本不使用多重采样并通过一些基于图像的后处理通道进行抗锯齿。

于 2015-08-03T19:47:13.260 回答