问题说明
我目前正在为延迟渲染器实现点光源,并且无法确定仅在灯光边界附近明显的重像素化/三角剖分来自何处。
问题似乎是由于某处的精度损失引起的,但我一直无法找到确切的来源。法线是一种明显的可能性,但我有一个同学正在使用directx,并且以类似的方式处理他的法线,没有任何问题。
距离我们游戏单位约 2 米(64 单位/米):
几厘米远。请注意,当我接近它时,“像素化”不会改变世界的大小。但是,如果我改变相机的方向,它似乎会游泳:
与我的前向渲染器的特写进行比较,它演示了使用 RGBA8 渲染目标所期望的球形条纹(每种颜色只有 0-255 个可能的值)。请注意,在我的延迟图片中,后墙显示出正常的球形条带:
光量在此处显示为绿色线框:
可以看出,除非您靠近表面(在我们的游戏单位中大约一米),否则效果是不可见的。
位置重建
首先,我应该提到我正在使用一个球形网格,我只使用它来渲染屏幕中光线重叠的部分。如果深度大于或等于此处建议的深度缓冲区,我只渲染背面。
为了重建片段的相机空间位置,我从光体积上的相机空间片段中获取矢量,对其进行归一化,并按我的 gbuffer 中的线性深度对其进行缩放。这是此处讨论的方法(使用线性深度)和此处(球形光量)的混合。
几何缓冲区
我的 gBuffer 设置是:
enum render_targets { e_dist_32f = 0, e_diffuse_rgb8, e_norm_xyz8_specpow_a8, e_light_rgb8_specintes_a8, num_rt };
//...
GLint internal_formats[num_rt] = { GL_R32F, GL_RGBA8, GL_RGBA8, GL_RGBA8 };
GLint formats[num_rt] = { GL_RED, GL_RGBA, GL_RGBA, GL_RGBA };
GLint types[num_rt] = { GL_FLOAT, GL_FLOAT, GL_FLOAT, GL_FLOAT };
for(uint i = 0; i < num_rt; ++i)
{
glBindTexture(GL_TEXTURE_2D, _render_targets[i]);
glTexImage2D(GL_TEXTURE_2D, 0, internal_formats[i], _width, _height, 0, formats[i], types[i], nullptr);
}
// Separate non-linear depth buffer used for depth testing
glBindTexture(GL_TEXTURE_2D, _depth_tex_id);
glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT32, _width, _height, 0, GL_DEPTH_COMPONENT, GL_FLOAT, nullptr);