gpt4 book ai didi

opengl - 使用 OpenGL 进行延迟渲染,在表面的光照边界附近经历严重的像素化

转载 作者:行者123 更新时间:2023-12-01 23:59:22 24 4
gpt4 key购买 nike

问题解释

我目前正在为延迟渲染器实现点光源,但无法确定仅在光源边界附近才明显的重像素化/三角剖分来自何处。

问题似乎是由某处的精度损失引起的,但我一直无法找到确切的来源。法线是一种明显的可能性,但我有一个同学正在使用 directx 并以类似的方式处理他的法线,没有任何问题。

大约 2 米远我们游戏的单位(64 单位/米):

deferred_full_scene

几厘米远。请注意,当我接近它时,“像素化”不会改变世界的大小。但是,如果我改变相机的方向,它会看起来像在游泳:

deferred_closeup

与我的前向渲染器的特写比较,它展示了人们对 RGBA8 渲染目标(每种颜色只有 0-255 个可能值)所期望的球形条纹。请注意,在我的延迟图片中,后壁显示出正常的球形条纹:

closeup_forward

光体积在这里显示为绿色线框:

light_volume_and_scene

可以看出,除非您靠近表面(在我们的游戏单位中大约一米),否则效果是不可见的。


位置重建

首先,我应该提到我使用的是球形网格,我用它来渲染光线重叠的屏幕部分。如果深度大于或等于深度缓冲区,我只渲染背面 as suggested here .

为了重建片段的相机空间位置,我从光体积上的相机空间片段中获取向量,对其进行归一化,并按 gbuffer 中的线性深度对其进行缩放。这是讨论的方法的混合体 here (using linear depth)here (spherical light volumes) .

position_reconstruction


几何缓冲区

我的 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);

最佳答案

普通精度

问题是我的法线没有足够的精度。每个组件 8 位,这意味着 255 个离散的可能值。检查覆盖在光照顶部的 gbuffer 中的法线显示与法线值与点亮“像素”值的 1-1 对应关系。

我不确定为什么我的同学没有遇到同样的问题(他将进一步调查)。

normal_precision

经过更多研究后,我发现一个术语是量化。另一个例子可以看here在第 19 页有镜面高光。


解决方案

将我的正常渲染目标更改为 RG16F 后,问题就解决了。

使用方法建议here存储和检索法线我得到以下结果:

no_quantization

我现在需要更紧凑地存储我的法线(我只有 2 个组件的空间)。 This如果有人发现自己处于同样的情况,这是一项很好的技术调查。


[编辑 1]

正如 Andon 和 GuyRT 在评论中指出的那样,16 位对于我的需要来说有点过大了。我已经按照他们的建议切换到 RGB10_A2,它给出了非常令人满意的结果,即使在圆形表面上也是如此。额外的 2 位有很大帮助(256 对 1024 个离散值)。

这是现在的样子。

enter image description here

还应注意(对于将来引用此帖子的任何人),我为 RG16F 发布的图像在我用于压缩/解压缩法线的方法中有一些不希望出现的 strip (涉及一些错误)。


[编辑 2]

在与一位同学(使用 RGB8 且没有任何不良影响)进一步讨论这个问题后,我认为值得一提的是,我可能只是拥有完美的元素组合才能使它出现。我正在为其构建此渲染器的游戏是一款恐怖游戏,可让您置身于漆黑的环境中,并具有类似声纳的能力。通常情况下,在一个场景中,您会有许多不同角度的灯光(我同学的环境都非常明亮 - 他们正在制作户外赛车游戏)。再加上它只出现在相对较近的非常圆的物体上,这可能就是我挑起这个的原因。这只是我的(受过一些教育的)猜测。

关于opengl - 使用 OpenGL 进行延迟渲染,在表面的光照边界附近经历严重的像素化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22295120/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com