OpenGL NDC 和坐标

标签 opengl glsl coordinates perspectivecamera

虽然我对 OpenGL 比较陌生,但我对矩阵代数、齐次坐标、旋转和投影没有任何困难。我已经设置了我的 mvp 矩阵以获得立方体的良好 View 并且它渲染得很好。

接下来,我不渲染立方体,而是尝试从 background image 读取颜色。 。正如预期的那样,纹理被渲染并剪裁到立方体所在的位置,但由于某种原因,存在相当大的失真。 (根据评论中的建议,我现在除以 w [认为 OpenGL 做到了这一点]。)

据我了解,NDC 中的 xy 坐标应该线性映射到窗口上。失真从何而来?

顶点着色器:

#version 330
uniform mat4 Mvp;

in vec3 in_shape;

out vec2 v_ndc;

void main() {
    gl_Position = Mvp * vec4(in_shape, 1.0);
    v_ndc = vec2(
        gl_Position.x / gl_Position.w,
        -gl_Position.y / gl_Position.w
    ) / 2 + 0.5;
}

片段着色器:

#version 330
uniform sampler2D Background;

in vec2 v_ndc;

out vec4 f_color;

void main() {
    f_color = vec4(texture(Background, v_ndc).rgb, 1.0);
}

结果

enter image description here

最佳答案

As far as I understand, the xy coordinates in NDC should map linearly onto the window. Where does the distortion come from?

gl_PositionHomogeneous coordinate你必须做Perspective divide

v_ndc = gl_Position.xy/gl_Position.w

注意,gl_Position.xy 是剪辑空间坐标。通过除以 w 分量,剪辑空间中的坐标将转换为 (-1, -1, -1) 到 (1, 1, 1) 范围内的标准化设备坐标 (NDC)剪辑坐标。


There is still distortion.

这是因为v ndc的插值是在透视图中完成的。它基于 Barycentric coordinates三角形基元的位置,由透视图中的 gl_Position 定义。

使用noperspective在窗口空间中进行线性插值:

顶点着色器:

noperspective out vec2 v_ndc;

片段着色器

noperspective in vec2 v_ndc;

另请参阅OpenGL Interpolation Qualifiers (GLSL)

关于OpenGL NDC 和坐标,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49262877/

相关文章:

android - 在 OpenGL 中将 alpha mask 应用于视频

c - 无法通过读取 x、y 坐标输入到数组来计算多边形的周长

c++ - 反转 X 轴 OpenGL

opengl - GLSL 分支行为

glsl - OpenFL - 为着色器提供时间

javascript - 如何通过 javascript 确定触摸事件(或鼠标事件)中的真实 x y 坐标?

java - 如何使用JTS简化线路?

c++ - 为 Qt5 指定 OpenGL 桌面而不是 ES

c++ - 为什么我无法在 OpenGL 中显示纹理?

c++ - OpenGL - 采摘(最快的方式)