为什么这个正交顶点着色器不能产生正确的答案?

时间:2011-08-07 19:09:32

标签: opengl shader vertex-shader

我的问题是我有一个(工作)正交顶点和片段着色器对,允许我通过传入'translateX'和'translateY'制服来指定精灵的中心X和Y.我乘以projectionMatrix那个是硬编码的,效果很好。一切都适用于正交操作。我到此着色器的传入几何图形基于0,0,0作为其中心点。

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

我的问题:我做错了什么,我怎么能调试发生了什么?我知道计算的值必定是错误的,但我对它的含义并不了解。 (我的平台是OS X开发的OpenGL ES 2.0 iOS上的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);
}

编辑:为了回应我的拼写矩阵错误,以下是wikipedia关于正投影的说法,而我的-1看起来正确。因为在我的情况下,例如我的垫子的第四个元素应该是 - ((右+左)/(右 - 左)),它是0的左边960的右边,所以-1 *(960/960)是-1

编辑:我可能在这里发现了根本问题 - what do you think?

enter image description here

2 个答案:

答案 0 :(得分:4)

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

我更关心这个:

gl_Position *= projectionMatrix;

这是什么意思?矩阵乘法不是可交换的; M * aa * 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中的矩阵是列专业。前四个值是矩阵的第一个,而不是第一行。您将乘以转置的正交矩阵。

答案 1 :(得分:1)

我必须回应尼科尔博拉斯的观点。为使事情有效而发生的两个错误令人沮丧,但并没有让它们变得更糟。因为矩阵的翻译部分是0,0,0,所以事情出现在你预期的位置很可能。

您发布的等式是正确的,但符号是行专业,OpenGL是专栏: 4 columns of the OpenGL's matrix

我开始每一个新项目都会碰到这些东西。 This site是一个非常好的资源,帮助我保持这些事情。他们在projection matrices上有另一页。

如果您不确定您的拼写投影是否正确(现在不是),请尝试将相同的值插入GL_PROJECTION的glOrthoreading the values back out