GLSL 奇怪地用于创建深度 G-Buffer

GLSL works weirdly for creating depth G-Buffer

下图为几何渲染结果

耶稣啊!我没有足够的声誉。然后我不能附上我的照片。 我描述几何,而不是附上我的照片。

几何形状是平面矩形。

那么下面的代码就是创建深度g-buffer的glsl源代码。

--- 顶点着色器 ---

varying float uv_depth;

void main (void) 
{
    vec4 pos = modelview_mat * vec4(v_pos,1.0);
    gl_Position = projection_mat * pos;
    uv_depth = gl_Position.z / gl_Position.w;
}

--- 片段着色器 ---

varying float uv_depth;

void main (void)
{
    float depthNormalized = uv_depth * 0.5 + 0.5;
    vec4 color = packFloatToVec4i(depthNormalized);
    gl_FragColor = color;
}

函数 packFloatToVec4i 是一个打包函数。没那么重要。

就像我上面说的,几何形状是平面矩形。 所以我期待非常流畅的图像。但事实并非如此。 深度 g 缓冲区很奇怪。

如我所料,有些地方很光滑。但整体不是。 部分部位有刺耳的起伏。

我认为制作深度G-buffer很容易。 但是我迷路了。 我的代码有问题吗? 请帮助我。

您的 varying float uv_depth 逻辑没有必要。

如果您了解 OpenGL 用来达到 window-space (gl_FragCoord) 的变换(投影、透视划分、视口映射),您会发现您并不根本不需要写uv_depth

片段着色器中行 float depthNormalized = uv_depth * 0.5 + 0.5; 计算的值实际上与 gl_FragCoord.z 存储的值相同。您基本上重新发明了视口变换(深度范围),它已经自动发生了。

如果您以这种方式编写片段着色器,您可能会获得更好的结果:

void main (void)
{
    vec4 color = packFloatToVec4i(gl_FragCoord.z);
    gl_FragColor = color;
}

理想情况下,您甚至不需要使用颜色纹理来存储深度。 GL_DEPTH_COMPONENT 图像格式效率更高,不需要特殊的打包和解包,它们可以存储具有存储深度所需精度的单个组件。