Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/132.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 反转几何图形为透视图填充位置。正字法可以吗?_C++_Opengl_Glsl_Glm Math_Opengl 4 - Fatal编程技术网

C++ 反转几何图形为透视图填充位置。正字法可以吗?

C++ 反转几何图形为透视图填充位置。正字法可以吗?,c++,opengl,glsl,glm-math,opengl-4,C++,Opengl,Glsl,Glm Math,Opengl 4,我有一个延迟渲染器,它看起来工作正常,深度、颜色和阴影显示正确。但是,位置缓冲区对于正交来说很好,而几何体在使用透视投影时显示为“反转”(或禁用深度) 我得到以下正交的缓冲输出 最终的“着色”图像当前看起来正确 然而,当我使用透视投影时,我会得到以下缓冲区 最后的图像很好,尽管我目前没有包含任何位置缓冲区信息(注意,目前只做“前照灯”着色) 虽然最终图像显示正确,但我的位置缓冲区的深度缓冲区似乎被忽略…(代码中没有glDisable(GL_depth_TEST)) 深度和法线缓冲

我有一个延迟渲染器,它看起来工作正常,深度、颜色和阴影显示正确。但是,位置缓冲区对于正交来说很好,而几何体在使用透视投影时显示为“反转”(或禁用深度)

我得到以下正交的缓冲输出

最终的“着色”图像当前看起来正确

然而,当我使用透视投影时,我会得到以下缓冲区

最后的图像很好,尽管我目前没有包含任何位置缓冲区信息(注意,目前只做“前照灯”着色)

虽然最终图像显示正确,但我的位置缓冲区的深度缓冲区似乎被忽略…(代码中没有glDisable(GL_depth_TEST))

深度和法线缓冲区在我看来还行,只是“位置”缓冲区似乎忽略了深度?渲染管道在正交和透视中完全相同,唯一的区别是投影矩阵

我使用
glm::ortho
glm::perspective
并根据场景AABB计算我的近/远剪裁距离。对于正交,我的近/远剪裁距离分别为1和11.4734,对于透视,我的近/远剪裁距离分别为11.0875和22.5609…宽度和高度值相同,对于透视投影,fov为45

在绘制任何几何图形之前,我确实有这些调用

glEnable(GL_DEPTH_TEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
我使用它作为渲染管道的一部分来合成不同的层

我在这里做错什么了吗?还是我误解了什么

这是我的着色器。。。 gBuffer的顶点着色器

#version 430 core

layout (std140) uniform MatrixPV
{
    mat4 P;
    mat4 V;
};

layout(location = 0) in vec3 InPoint;
layout(location = 1) in vec3 InNormal;
layout(location = 2) in vec2 InUV;

uniform mat4 M;

out vec4 Position;
out vec3 Normal;
out vec2 UV;

void main()
{
    mat4 VM = V * M;
    gl_Position = P * VM * vec4(InPoint, 1.0);
    Position = P * VM * vec4(InPoint, 1.0);
    Normal = mat3(M) * InNormal;
    UV = InUV;
}
#version 430 core

layout(location = 0) out vec4 gBufferPicker;
layout(location = 1) out vec4 gBufferPosition;
layout(location = 2) out vec4 gBufferNormal;
layout(location = 3) out vec4 gBufferDiffuse;

in vec3 Normal;
in vec4 Position;

vec4 Diffuse();
uniform vec4 PickerColour;

void main()
{
    gBufferPosition = Position;
    gBufferNormal = vec4(Normal.xyz, 1.0);
    gBufferPicker = PickerColour;
    gBufferDiffuse = Diffuse();
}
gBuffer的片段着色器

#version 430 core

layout (std140) uniform MatrixPV
{
    mat4 P;
    mat4 V;
};

layout(location = 0) in vec3 InPoint;
layout(location = 1) in vec3 InNormal;
layout(location = 2) in vec2 InUV;

uniform mat4 M;

out vec4 Position;
out vec3 Normal;
out vec2 UV;

void main()
{
    mat4 VM = V * M;
    gl_Position = P * VM * vec4(InPoint, 1.0);
    Position = P * VM * vec4(InPoint, 1.0);
    Normal = mat3(M) * InNormal;
    UV = InUV;
}
#version 430 core

layout(location = 0) out vec4 gBufferPicker;
layout(location = 1) out vec4 gBufferPosition;
layout(location = 2) out vec4 gBufferNormal;
layout(location = 3) out vec4 gBufferDiffuse;

in vec3 Normal;
in vec4 Position;

vec4 Diffuse();
uniform vec4 PickerColour;

void main()
{
    gBufferPosition = Position;
    gBufferNormal = vec4(Normal.xyz, 1.0);
    gBufferPicker = PickerColour;
    gBufferDiffuse = Diffuse();
}
这里是“第二遍”着色器,用于可视化位置缓冲区

#version 430 core

uniform sampler2D debugBufferPosition;

in vec2 UV;
out vec4 frag;

void main()
{
    vec3 val = texture(debugBufferPosition, UV).xyz;
    frag = vec4(val.xyz, 1.0);
}

我还没有使用位置缓冲区数据,我知道我可以重建它,而不必将它们存储在另一个缓冲区中,但是由于其他原因,这些位置对我很有用,我想知道为什么它们会以透视图的形式出现?

在位置缓冲区中实际写入的是剪辑空间坐标

Position=P*VM*vec4(InPoint,1.0);
剪辑空间坐标为a,并转换为法线化设备坐标(由a表示)

ndc=gl_Position.xyz/gl_Position.w;
在正交投影中,
w
分量为1,但在透视投影中,
w
分量包含一个值,该值取决于(笛卡尔)视图空间坐标的
z
分量(深度)

我建议将标准化设备坐标存储到位置缓冲区,而不是剪辑空间坐标。例如:

gBufferPosition=vec4(Position.xyz/Position.w,1.0);

谢谢。位置缓冲区的视觉效果现在与我将其导出的外观相同:)。如果可以的话,请再问一个问题?您建议将位置存储为ndc,这是为什么?我希望有一个位置缓冲区的主要原因之一,主要是为了能够通过将位置图像与
glReadPixels
进行互光栅化来查询任何给定点的位置,而不必在CPU上执行转换(虽然有第二个想法,因为我有很多备用GPU循环),但也可能有助于SSAO。因此,直接在视图/眼睛(剪辑)空间中存储位置不是更好吗?很多thanks@lfgtm我的意思是,与剪辑空间坐标相比,存储NDC坐标更好(您已经存储了剪辑空间坐标)。当然,如果您需要查看空间或世界空间坐标,请将其存储到缓冲区。好的,我将进行实验。是的,我现在考虑使用GPU从深度重建此坐标。非常感谢您的时间和帮助,非常感谢:)