Почему этот ортогональный вершинный шейдер не дает правильного ответа? - PullRequest
4 голосов
/ 07 августа 2011

Моя проблема в том, что у меня есть (рабочая) пара вершинных и фрагментарных шейдеров, которые позволяют мне указывать центр X и Y спрайта через передаваемые формы 'translateX' и 'translateY'. Я умножаю на матрицу projectionMatrix, котораяжестко запрограммирован и прекрасно работает.Все работает, насколько орфографическая операция.Моя входящая геометрия для этого шейдера основана на 0, 0, 0 в качестве его центральной точки.

Теперь я хочу выяснить, какой будет эта центральная точка (0, 0, 0 в локальном координатном пространстве) после переводов,Мне нужно знать эту информацию во фрагментном шейдере.Я предположил, что я могу создать вектор в 0, 0, 0 и затем применить те же переводы.Тем не менее, я НЕ получаю правильный ответ.

Мой вопрос: что я делаю неправильно, и как я могу даже отладить, что происходит?Я знаю, что вычисляемое значение должно быть неверным, но я не понимаю, что это такое.(Моя платформа - Xcode 4.2 на OS X, разрабатываемая для OpenGL ES 2.0 iOS)

Вот мой вершинный шейдер:

// 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-й элемент моего мата должен быть - ((правый + левый) / (правый левый)) справа от 960 слева от 0, поэтому -1 * (960/960) это -1.

РЕДАКТИРОВАТЬ: Я, возможно, обнаружил корневую проблему здесь - что вы думаете?

enter image description here

Ответы [ 2 ]

4 голосов
/ 08 августа 2011

Почему ваша орто-матрица имеет -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;. Вам нужно будет заполнить Z и W константами (gl_Position.zw = vec2(0, 1);).


Матрицы в GLSL: основной столбец . Первые четыре значения - это первый столбец матрицы, а не первая строка. Вы умножаете на транспонированную орто-матрицу.

1 голос
/ 11 августа 2011

Я должен повторить настроение Николь Болас. Два зла, случающиеся, чтобы заставить вещи работать, расстраивают, но не делают их менее неправильными. Тот факт, что вещи появляются там, где вы ожидаете, скорее всего, потому что часть перевода вашей матрицы равна 0, 0, 0.

Уравнение, которое вы опубликовали, является правильным, но обозначение является основным, а OpenGL - главным столбцом: 4 columns of the OpenGL's matrix

Я сталкиваюсь с этими вещами каждый новый проект, который начинаю. Этот сайт - действительно хороший ресурс, который помог мне разобраться в этом. У них есть еще одна страница о матрицах проекций .

Если вы не уверены, что ваша ортографическая проекция верна (сейчас это не так), попробуйте вставить те же значения в glOrtho и , считывая значения обратно GL_PROJECTION.

...