1

In the book of 3D graphics for game programming by JungHyun Han, at page 38-39, it is given that

the basis transformation matrix from e_1, e_2, e_3 to u,v,n is enter image description here

However, this contradicts with what I know from linear algebra. I mean shouldn't the basis-transformation matrix be the transpose of that matrix ?

Note that the author does his derivation, but I couldn't find where is the missing point between what I know and what the author does.

The code: Vertex Shader:

#version 330
layout(location = 0) in vec4 position;
layout(location = 1) in vec4 color;

uniform vec3 cameraPosition;
uniform vec3 AT;
uniform vec3 UP;
uniform mat4 worldTrans;

vec3 ep_1 = ( cameraPosition - AT )/ length(cameraPosition - AT);
vec3 ep_2 = ( cross(UP, ep_1) )/length( cross(UP, ep_1 )); 
vec3 ep_3 = cross(ep_1, ep_2);

vec4 t_ep_1 = vec4(ep_1, -1.0f);
vec4 t_ep_2 = vec4(ep_2, cameraPosition.y);
vec4 t_ep_3 = vec4(ep_3, cameraPosition.z);
mat4 viewTransform = mat4(t_ep_1, t_ep_2, t_ep_3, vec4(0.0f, 0.0f, 0.0f, 1.0f));

smooth out vec4 fragColor;
void main()
{
    gl_Position = transpose(viewTransform) * position;
    fragColor = color;
}
)glsl";

Inputs:

GLuint transMat = glGetUniformLocation(m_Program.m_shaderProgram, "worldTrans");
    GLfloat dArray[16] = {0.0};
    dArray[0] = 1;
    dArray[3] = 0.5;
    dArray[5] = 1;
    dArray[7] = 0.5;
    dArray[10] = 1;
    dArray[11] = 0;
    dArray[15] = 1;
    glUniformMatrix4fv(transMat, 1, GL_TRUE, &dArray[0]);
    GLuint cameraPosId = glGetUniformLocation(m_Program.m_shaderProgram, "cameraPosition");
    GLuint ATId = glGetUniformLocation(m_Program.m_shaderProgram, "AT");
    GLuint UPId = glGetUniformLocation(m_Program.m_shaderProgram, "UP");
    const float cameraPosition[4] = {2.0f, 0.0f, 0.0f};
    const float AT[4] = {1.0f, 0.0f, 0.0f};
    const float UP[4] = {0.0f, 0.0f, 1.0f};
    glUniform3fv(cameraPosId, 1, cameraPosition);
    glUniform3fv(ATId, 1, AT);
    glUniform3fv(UPId, 1, UP);
Our
  • 986
  • 12
  • 22
  • The meaning of terminology *transformation matrix* is not the same, it depends on the book and author. Just write it down in non-matrix form to check whether it's correct. – llllllllll Jan 19 '18 at 18:13
  • @liliscent I have done that already, and it should be wrong, but when I test it actually, what the author says works, but I do not know why. – Our Jan 19 '18 at 18:14
  • If you think it should be transposed, first check the representation of vector, in row form or column form. Sometimes there will be a use of that term with an inverse. I think people use it just in the way they prefer. – llllllllll Jan 19 '18 at 18:18
  • @liliscent See my edit also. – Our Jan 19 '18 at 18:26
  • @Rabbid76 Thanks for the info, but I couldn't see the missing point. – Our Jan 19 '18 at 18:26
  • may be this [Understanding 4x4 homogenous transform matrices](https://stackoverflow.com/a/28084380/2521214) will shine some light on the topic for you. The transpose part is true just for the rotational part of the matrix (`3x3`) the offsets are computed a bit diferently... As mentioned in the comments what is transposed and what not depends on the convention used – Spektre Jan 22 '18 at 09:44
  • @Spektre See my answer. – Our Jan 22 '18 at 10:24

2 Answers2

1

While it's true that a rotation, scaling or deformation can be expressed by a 4x4 matrix in the form enter image description here

what your are reading about is the so called "View Transformation"

To achieve this matrix we need two transformations: First, translate to the camera position, and then rotate the camera.

The data to do these transformations are:

  • Camera position C (Cx,Cy,Cz)
  • Target position T (Tx,Ty,Tz)
  • Camera-up normalized UP (Ux, Uy, Uz)

The translation can be expressed by

enter image description here

For the rotation we define:
F = T – C and after normalizating it we get f = F / ||T-C||, also expressed by f= normalize(F)
s = normalize(cross (f, UP))
u = normalize(cross(s, f))

s, u, -f are the new axis expressed in the old coordinates system.

Thus we can build the rotation matrix for this transformation as enter image description here

Combining the two transformations in an only matrix we get: enter image description here enter image description here

Notice that the axis system is the one used by OpenGL, where -f= cross(s,u).

Now, comparing with your GLSL code I see:

  1. Your f(ep_1) vector goes in the oposite direction.
  2. The s(ep_2) vector is calculated as cross(UP, f) instead of cross(f, UP). This is right, because of 1).
  3. Same for u(ep_3).
  4. The building of V cell (0,0) is wrong. It tries to set the proper direction by using that -1.0f.
  5. For the other cells (t_ep_J components), the camera position is used. But you forgot to use the dot product of it with s,u,f.
  6. The GLSL initializer mat4(c1,c2,c3,c4) requires column-vectors as parameters. You passed row-colums. But, after, in main the use of transpose corrects it.

On a side note, you are not going to calculate the matrix for each vertex, time and time and time... right? Better calculate it on the CPU side and pass if (in column order) as an uniform.

Ripi2
  • 7,031
  • 1
  • 17
  • 33
0

Apparently, the change of basis in a vector space does changes the vectors in that vector space, and this is not what we want in here.

Therefore, the mathematics that I was applying does not valid in here.

To understand more about why we use the matrix that I have given in the question, please see this question.

Our
  • 986
  • 12
  • 22