我想验证这是一种有效的方法,而且我不会忽视某些内容。
我正在使用球形网格,我只使用它来渲染光线重叠的屏幕部分。如果深度大于或等于深度缓冲区as suggested here,则仅渲染背面。
要重建片段的相机空间位置,我将从光量上的相机空间片段中取出矢量,对其进行标准化,并使用我的gbuffer中的线性深度进行缩放(这是存储为 32位浮点数)。这类似于所讨论的方法here (using linear depth)和here (spherical light volumes)的混合。
我问的原因是因为我从延迟vs前向获得的光衰减结果是不同的。
延迟
转发
衰减与我的相机空间位置相关联,因为我按如下方式计算衰减:
vec3 light_dir_to = curr_light.camera_space_position - surface_pos_cam;
float light_dist_sq = dot(light_dir_to, light_dir_to);
float light_attenuation_factor = 1.0f - ((1.0f / (curr_light.radius * curr_light.radius)) * light_dist_sq);
light_attenuation_factor = clamp(light_attenuation_factor, 0.0f, 1.0f);
light_attenuation_factor = pow(light_attenuation_factor, curr_light.falloff);
在这些情况下,差异并不是特别明显,但是我尝试缩放光线的例子(例如,将其提升到能够使其淡出更快的力量),效果立即显现出来。
light_atten = pow(light_atten,2.0f)
我的问题可能在其他地方,但我想验证我的位置重建方法在某种程度上是不容忽视的。
按要求发布我的gbuffer设置。
enum render_targets { e_dist_32f = 0, e_diffuse_rgb8, e_norm_xyz10, e_spec_intens_b8_spec_pow_a8, e_light_rgb8, num_rt };
//...
GLint internal_formats[num_rt] = { GL_R32F, GL_RGBA8, GL_RGB10_A2, GL_RGBA8, GL_RGBA8 };
GLint formats[num_rt] = { GL_RED, GL_RGBA, GL_RGBA, GL_RGBA, GL_RGBA };
GLint types[num_rt] = { GL_FLOAT, 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);
注意:在整个曲面上有一个法线的平面上会出现此问题,因此这不会对法线造成精度损失。
似乎这种方法实际上是有效的(如GuyRT所述)。条带问题似乎来自于我如何进行伽马校正。
对于我的前向渲染器,我只有一个循环超过8个灯光(我不进行多次传递,仅1次传递),并且我在光照计算后立即应用伽玛校正。
对于我的延迟渲染器,我会进行所有照明计算,后期处理等,然后转换为gamma。这里的问题是我:
例如,假设两个片段的光照计算在sRGB空间中具有最终值1/255(~0.003)和2/255(~0.007)(如最后所示)。 RGB空间中的这些值是(1/255)^ 2.2 = ~0.000006和(2/255)^ 2.2 = ~0.00002。当这些值存储到我的光照累积纹理时,它们都存储为相同的值0.这是条带的原因。
将我的灯光累积纹理转换为 GL_R11F_G11F_B10F 已经产生了非常接近我的前向渲染器的结果。一旦我发现伽玛是问题,这两个问题的答案就帮助了我:sRGB textures. Is this correct?和When to call glEnable(GL_FRAMEBUFFER_SRGB)?。
&#34;衰退的最终结果&#34; 4.0分
我刚刚发现这种效果被称为&#34; Gamma Banding&#34;,这是有道理的。这是website has some useful charts和this video has a nice numerical walkthrough。
答案 0 :(得分:2)
经过一些调整,我认为你的方法是有效和可行的。
这看起来非常像所讨论的人工制品here。它是由g-buffer法线中的精度损失引起的。在这种情况下,解决方案是使用GL_RGB10_A2
格式来存储法线。
如果你有兴趣,可以在这里讨论g-buffer法线的替代表示:http://aras-p.info/texts/CompactNormalStorage.html,虽然有点旧,所以今天的ALU /带宽权衡可能会有所不同。另外,我认为他在他对视空间法线的讨论中犯了一个(很常见的)错误,其中 可能是负面的z分量。