Search code examples
opengl-esglslvertex-shader

GLSL Shader - How to calculate the height of a texture?


In this question I asked how to create a "mirrored" texture and now I want to move this "mirrored" image down on the y-axis about the height of the image. I tried something like this with different values of HEIGHT but I cannot find a proper solution:

// 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);
}

Solution

  • What you are actually changing in your code snippet is the Y position of your vertices... this is most certainly not what you want to do.
    a_position is your model-space position; the coordinate system that is centered around your quad (I'm assuming you're using a quad to display the texture).

    If instead you do the modification in screen-space, you will be able to move the image up and down etc... so change the gl_Position value:

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

    Note that then you will be in screen-space; so check the dimensions of your viewport.

    Finally, a better way to achieve the effect you want to do is to use a rotation matrix to flip and tilt the image.
    You would then combine this matrix with the rotation of you image (combine it with the modelviewmatrix).

    You can choose to either multiply the model matrices by the view projection on the 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;
    

    or on the 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;