OpenGL中的反向深度缓冲区是否需要更改顶点着色器?

falq053o  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(187)

我读过很多关于什么是以及如何在OpenGL中设置反向深度缓冲区的文章(只要在Google上搜索opengl reversed depth,我就读了6个位置),没有一个提到任何顶点着色器的变化。
只需4个步骤:
1.设置剪辑控制
1.将深度缓冲区清除为0
1.在投影矩阵中交换近平面和远平面
1.使用GL_GREATERGL_GEQUAL
所以我坐下来写了一个简单的类来渲染一个3D网格(assimp作为导入器)。没什么花哨的,它加载一个网格并使用Draw()函数绘制它。我已经为反向深度缓冲区配置了这4个步骤。

//step 1
glClipControl(GL_LOWER_LEFT, GL_ZERO_TO_ONE);

//step 2
float color[] = {0.1f, 0.1f, 0.1f, 1.0f};
glClearBufferfv(GL_COLOR, 0, color);
glClearBufferfi(GL_DEPTH_STENCIL, 0, 0.0f, 1);

//step 3
float fov = glm::radians(60.0f);
float aspect = 800.0f / 600.0f;
float near = 0.1f;
float far = 1000.0f;
auto proj = glm::perspective(fov, aspect, far, near);

//step 4
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_GREATER);

//meanwhile create and bind a uniform buffer for view, projection etc. matrices

mesh.Draw();

字符串
代码在我看来没问题,所以我运行了应用程序,没有网格渲染。我通过RenderDoc运行了它,一切似乎都很好。
顶点着色器:

#version 460 core

layout(location = 0) in vec3 a_position;
layout(location = 1) in vec3 a_normal;
layout(location = 2) in vec3 a_tangent;
layout(location = 3) in vec3 a_binormal;
layout(location = 4) in vec2 a_uv;

layout(location = 0) out vec2 v_uv;

layout(std140, binding = 0) uniform FrameUniforms
{
    mat4 viewProjection;
} u_frame;

layout(std140, binding = 1) uniform InstanceData
{
    mat4 model;
} u_instanceData;

void main()
{
    v_uv = vec2(a_uv.x, 1.0f - a_uv.y);

    vec4 position = u_frame.viewProjection * u_instanceData.model * vec4(a_position, 1.0);
    gl_Position = position;
}


我看不出哪里不对劲。
我又读了一遍这些文章,没有关于顶点着色器的文章,所以我问:“为什么它不工作?”
我的想法是“如果OpenGL的默认深度范围是[-1,+1],也许我必须改变顶点的位置。但是我已经在DX11中做了一个反向深度缓冲,它已经工作了......而且,修改顶点z位置没有意义,因为我已经测试了深度范围为[0,1]但不反转深度缓冲区值”。尽管我认为这可能很愚蠢,但我还是做了这样的事情:
position.z = position.z * -0.5 + 0.5;
然后砰的一声,现在网格出现在屏幕上...
我的问题是,vertex .z的值必须修改,这一点是不是很明显,所以这些文章都没有提到这一点?
OpenGL和DX11之间有什么区别,我必须在OpenGL中完成它?
还是我漏掉了什么?

mqxuamgl

mqxuamgl1#

这是我使用的投影函数的问题。
使用glm::perspectiveZO();而不是glm::perspective();修复了问题

相关问题