2

I am using python's cgkit Mat44.lookat method and I am wondering if it is implemented correctly. I wrote the author but got no answer so far. My question is maybe silly, but I would really like to understand what's wrong in my program.

if I do :

camera_to_world_matrix = mat4.lookAt(eye=vec3(0,0,1), target=vec3(0,0,-3), up=vec3(0,1,0))
world_to_camera_matrix = camera_to_world_matrix.inverse()
pos_in_camera_space = world_to_camera_matrix * vec3(0,0,-10)

In my opinion, pos_in_camera_space should equal to vec3(0,0,-11) : the distance is 11 units between the two positions and as we are in a right handed system, the camera look toward the negative part of the z axis.

But I get vec3(0,0,11) and I don't see why.

edit : I use OpenGl3 and therefore shaders.

LBarret
  • 1,113
  • 10
  • 23

1 Answers1

2

The handedness is actually resolved by your projection matrix in the very end. You can invert the handedness of all of your transformations merely by making (0,0) the top-left corner of your screen instead of bottom-left for instance (glOrtho (0, width, 0, height, -1, 1) vs. glOrtho (0, width, height, 0, -1, 1)).

The reason gluLookAt (...) produces a right-handed transformation is because the matrix functions in GL that are used to establish the projection matrix (e.g. glOrtho (...) and glFrustum (...)) invert the Z coordinate. It is only when you combine the two matrices that you have a right-handed view space. Since they are inseparable in fixed-function OpenGL this point goes largely unnoticed.

For a more thorough explanation with diagrams, see this related question: Is OpenGL coordinate system left-handed or right-handed?

Community
  • 1
  • 1
Andon M. Coleman
  • 42,359
  • 2
  • 81
  • 106
  • I am tryong to wrap my head around the different space but there is something I don't understand : a lookAt computation is different from a combination of translation & rotation ? – LBarret Oct 03 '13 at 08:26
  • In my mental model, the camera is an object like any other, and the lookAt computation just a convenience function to orient it correctly. – LBarret Oct 03 '13 at 08:33
  • 1
    @LionelBarret: No, what I was trying to say in my answer is that OpenGL's coordinate system is only right-handed (and this actually depends on the coordinate space you are referring to, it differs between stages) when combined with a proper projection matrix (because NDC is actually left-handed). ["Why the negations? OpenGL wants to present to the programmer a right-handed coordinate system before projection and left-handed coordinate system after projection."](http://www.opengl.org/archives/resources/faq/technical/depthbuffer.htm). Hopefully that link will make things a little bit clearer. – Andon M. Coleman Oct 04 '13 at 15:47
  • 1
    @LionelBarret: I want to add to this, that if you use shaders you can completely ignore all of this (with the exception of the point about NDC). Knowing that NDC is left-handed and the viewport transform is _still_ fixed-function in modern OpenGL, you can implement `LookAt` anyway you want when you do vertex transformation using vertex shaders. You can invert the depth range to change the handedness in what is left of the fixed-function pipeline in modern (shader-based) OpenGL. – Andon M. Coleman Oct 04 '13 at 15:58
  • I do use shaders. And I think that's where the confusion is coming from. If I understance correctly, in a fixed pipeline, the lookat function needs to behave in a specific way to be compatible with glOrtho & others. But in a modern pipeline, the lookat function should be just a convenience function for camera orientation. The two have the same goals but in different contexts and therefore produce different results. Am I right ? Anyway, I'll check the green mark, you have been very helpful. – LBarret Oct 05 '13 at 14:45
  • 1
    Exactly, in a modern pipeline, where you are passing the matrices used for transformation directly to your vertex shader you can ignore the legacy of OpenGL. This is great news in the long-run, one less difference between APIs like OpenGL and D3D (however you still have to deal with row-major vs. column-major notation, etc. - this can be overridden in newer versions of GLSL, though almost nobody does it). In another 10 years some graphics engines will go as far as implementing the complete graphics pipeline in compute shaders (rasterization and all) and will laugh at our silly GL/D3D-isms. – Andon M. Coleman Oct 05 '13 at 16:17