4

我的问题是我有一个(工作的)正交顶点和片段着色器对,允许我通过传入的“translateX”和“translateY”制服指定精灵的中心 X 和 Y。我乘以一个硬编码的 projectionMatrix 和效果很好。就正交运算而言,一切都有效。我传入此着色器的几何图形以 0、0、0 为中心点。

我现在想弄清楚平移后的中心点(局部坐标空间中的 0、0、0)变成了什么。我需要在片段着色器中知道这些信息。我假设我可以在 0、0、0 处创建一个向量,然后应用相同的平移。但是,我没有得到正确的答案。

我的问题:我做错了什么,我怎么能调试发生了什么?我知道正在计算的值一定是错误的,但我不知道它是什么。(我的平台是为 OpenGL ES 2.0 iOS 开发的 OS X 上的 Xcode 4.2)

这是我的顶点着色器:

// Vertex Shader for pixel-accurate rendering
attribute vec4 a_position;
attribute vec2 a_texCoord;

varying vec2 v_texCoord;

uniform float translateX;
uniform float translateY;

// Set up orthographic projection 
// this is for 640 x 960
mat4 projectionMatrix = mat4( 2.0/960.0, 0.0, 0.0, -1.0,
                             0.0, 2.0/640.0, 0.0, -1.0,
                             0.0, 0.0, -1.0, 0.0,
                             0.0, 0.0, 0.0, 1.0);                        

void main()
{
    // Set position
    gl_Position = a_position;

    // Translate by the uniforms for offsetting
    gl_Position.x += translateX;
    gl_Position.y += translateY;

    // Translate
    gl_Position *= projectionMatrix;


    // Do all the same translations to a vector with origin at 0,0,0
    vec4 toPass = vec4(0, 0, 0, 1); // initialize.  doesn't matter if w is 1 or 0
    toPass.x += translateX;
    toPass.y += translateY;
    toPass *= projectionMatrix;

    // this SHOULD pass the computed value to my fragment shader.
    // unfortunately,  whatever value is sent, isn't right.
    //v_translatedOrigin = toPass;

    // instead, I use this as a workaround, since I do know the correct values for my
    // situation.  of course this is hardcoded and is terrible.
    v_translatedOrigin = vec4(500.0, 200.0, 0.0, 0.0);
}

编辑:作为对我的正交矩阵错误的回应,以下是维基百科关于正交投影的说法,而我的 -1 看起来是正确的。因为在我的情况下,例如我的垫子的第 4 个元素应该是 -((right+left)/(right-left)),它是 0 左边 960 的右边,所以 -1 * (960/960) 是 -1 .

编辑:我可能在这里发现了根本问题——你怎么看?

在此处输入图像描述

4

2 回答 2

4

为什么您的正交矩阵在每列的底部都有-1?那些应该是零。当然,这不应该影响任何事情。

我比较关心这个:

gl_Position *= projectionMatrix;

这意味着什么?矩阵乘法不可交换M * a不一样a * M。那么,您希望在哪一边gl_Position成倍增长?

奇怪的是,GLSL 规范没有说明(我对此提交了错误报告)。因此,您应该选择保证有效的方法:

gl_Position = projectionMatrix * gl_Position;

此外,您应该使用正确的矢量化代码。你应该有一个translate制服,这是一个vec2。然后你就可以做gl_Position.xy = a_position.xy + translate;。您必须用常数 ( gl_Position.zw = vec2(0, 1);)填充 Z 和 W。


GLSL 中的矩阵是column major。前四个值是矩阵的第一,而不是第一行。您正在与转置的正交矩阵相乘。

于 2011-08-07T20:12:45.337 回答
1

我必须附和尼可波拉斯的观点。发生两个错误以使事情正常进行是令人沮丧的,但并没有减少他们的错误。事情出现在您期望的位置很可能是因为矩阵的平移部分是 0、0、0。

您发布的等式是正确的,但符号是行主要的,而 OpenGL 是列主要的: OpenGL矩阵的4列

我开始的每个新项目都会与这些东西发生冲突。 这个网站是一个非常好的资源,它帮助我保持这些事情的正确性。他们有另一页关于投影矩阵

如果您不确定您的正交投影是否正确(现在不正确),请尝试将相同的值插入glOrtho,然后从 GL_PROJECTION 中读取值

于 2011-08-11T13:39:05.477 回答