2012-03-06 4 views
0

Вопрос this Я спросил, как создать «зеркальную» текстуру, и теперь я хочу переместить это «зеркальное» изображение вниз по оси Y относительно высоты изображения. я пытался что-то подобное с различными значениями высоты, но я не могу найти правильное решение:GLSL Shader - Как рассчитать высоту текстуры?

// Vertex Shader 
uniform highp mat4 u_modelViewMatrix; 
uniform highp mat4 u_projectionMatrix; 
attribute highp vec4 a_position; 
attribute lowp vec4 a_color; 
attribute highp vec2 a_texcoord; 
varying lowp vec4 v_color; 
varying highp vec2 v_texCoord; 
void main() 
{ 
    highp vec4 pos = a_position; 
    pos.y = pos.y - HEIGHT; 
    gl_Position = (u_projectionMatrix * u_modelViewMatrix) * pos; 
    v_color = a_color; 
v_texCoord = vec2(a_texcoord.x, 1.0 - a_texcoord.y); 
} 

ответ

3

Что вы на самом деле изменяете в своем фрагменте кода - это позиция Y ваших вершин ... это, безусловно, не то, что вы хотите сделать.
a_позиция - позиция вашего модельного пространства; система координат, которая сосредоточена вокруг вашего квадроцикла (я предполагаю, что вы используете квадрант для отображения текстуры).

Если вместо этого вы делаете изменения в экранном пространстве, вы будете иметь возможность перемещать изображение вверх и вниз и т.д. ... так изменить значение gl_Position:

((u_projectionMatrix * u_modelViewMatrix) * pos + Vec4(0,HEIGHT,0,0)) 

Обратите внимание, что тогда вы будете в экранное пространство; поэтому проверьте размеры вашего окна просмотра.

Наконец, лучший способ добиться эффекта, который вы хотите сделать, - использовать матрицу поворота для переворота и наклона изображения.
Затем вы объедините эту матрицу с вращением изображения (объедините его с моделью viewmatrix).

Вы можете выбрать либо умножить матрицы модели на вид проекции на CPU:

original_mdl_mat = ...; 
rotated_mdl_mat = Matrix.CreateTranslation(0, -image.Height, 0) * Matrix.CreateRotationY(180) * original_mdl_mat; 
mvm_original_mat = Projection * View * original_mdl_mat; 
mvm_rotated_mat = Projection * View * rotated_mdl_mat; 

или на GPU:

uniform highp mat4 u_model; 
uniform highp mat4 u_viewMatrix; 
uniform highp mat4 u_projectionMatrix; 
gl_Position = (u_projectionMatrix * u_model * u_viewMatrix) * pos; 
+0

но еще мне нужно найти способ расчета Значение HEIGHT, как упоминал Томми. Я попробовал его с матрицей вращения, но как убедиться, что повернутое изображение всегда прямо под исходным изображением? – seveves

+0

Для высоты вы можете пройти в форме и сделать HEIGHT/viewport_height. Однако лучший способ - сделать эту сторону ЦП с матрицей. Чтобы убедиться, что это всегда правильно, вы можете сделать что-то подобное в коде CPP/ObjC: original_mdl_mat = ...; rotated_mdl_mat = Matrix.CreateTranslation (0, -image.Height, 0) * Matrix.CreateRotationY (180) * original_mdl_mat; Затем передайте original_mdl_mat в свой шейдер Vertex, чтобы отобразить нормальное изображение, и rotated_mdl_mat, чтобы отобразить повернутый. Примечание: здесь я использую нотацию DirectX/XNA, но вы можете адаптировать ее для OpenGL-ES. –

+0

Проблема в том, что я не влияю на происходящее на процессоре, потому что im программирует на интерфейс, который позволяет изменять шейдеры, а интерфейс не обеспечивает модель, просмотр и проекцию отдельно. У меня есть только доступ к модели в сочетании с матрицей вида и матрицей проецирования. Другая матрица, предоставляемая интерфейсом, является нормальной матрицей. – seveves

1

координаты, передаваемые в texture2D всегда образец источника в диапазоне [0, 1) по обеим осям, независимо от того, оригинальный размер текстуры и соотношение сторон. Таким образом, ответ на коленец заключается в том, что высота текстуры всегда равна 1,0.

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