OpenGL设备坐标着色器表现异常

时间:2017-06-10 06:45:23

标签: opengl 3d glsl shader

我有一个OpenGL应用程序,它表现出我不理解的行为。应用程序由背景上的长方体组成,长方体根据它在屏幕上的位置进行着色,使用以下代码:

顶点着色器:

#version 450 core

//In from VBO
in vec3 position;
in vec2 uv;
in vec3 normal;

//Out to Fragment Shader
out vec4 screenPos;
out vec4 fragPosition;
out vec2 fragUV;
out vec3 fragNormal;

//3D Uniforms
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    //Screen translation
    vec4 vertex = model * vec4(position, 1.0);

    gl_Position = projection * view * vertex;
    screenPos = projection * view * vertex;

    //Out to Fragment Shader
    fragPosition = vertex;
    fragUV = uv;
    fragNormal = normal;
}

片段着色器:

#version 450 core

//From Vertex Shader
in vec4 screenPos;
in vec4 fragPosition;
in vec2 fragUV;
in vec3 fragNormal;

//To Target
out vec4 fragmentColor;

void main()
{
    fragmentColor = vec4(screenPos.x, screenPos.y, 0.0, 1.0);
}

当我运行这个时,我得到一个明显受启发的屏幕位置结果,但是没有按预期运行,如下所示。 (感兴趣的对象是前景中的绿色/红色/黑色长方体,背景表现得如预期的那样)。

The problem

黑暗与光相遇的地方应位于屏幕的中心,因为设备坐标(两个轴上的介于-1和1之间)从负(无颜色)过渡到正(绿色和/或红色)颜色)。然而事实并非如此,它与屏幕中心的距离显着偏离,而正负相位之间的线应该是垂直/水平的。发生了什么事?

1 个答案:

答案 0 :(得分:2)

发生了什么事情,你没有提供标准化的设备坐标。您提供了剪辑空间坐标。要获得NDC空间,您必须divide the XYZ components of clip-space by the clip-space W

但是,如果您只想要片段的位置,则使用gl_FragCoord in the fragment shader会更容易。它没有标准化,但您可以通过提供指定the viewport values的统一来轻松地将其标准化。然后只需做一些数学运算来标准化uniform vec2 viewportOffset; uniform vec2 viewportSize; vec2 NormalizePosition() { vec2 temp = gl_FragCoord.xy - viewportOffset - (viewportSize/2); return temp * (2 / viewportSize); }

SELECT  COUNT(*) as cnt, GROUP_CONCAT(id) AS ids
    FROM  `table`
    GROUP BY  col1, col2, col3, col4, col5, col6, col7, col8, col9, col10
    HAVING  cnt > 1';