ao11's picture

Matrix4.LookAt understanding

Hello,

I just startet with OpenTK and OpenGL.

So for my understanding the Matrix4.LookAt call can be used to create the "Camera" which looks at the scene.

To play around I created a flat scene containing some tiles with:

GL.Begin(BeginMode.Quads);
 
GL.Color3(m_c); // m_c holding a Color
 
GL.Vertex2((float)(m_x + 0) * Config.factor, (float)(m_y + 0) * Config.factor);
GL.Vertex2((float)(m_x + 1) * Config.factor, (float)(m_y + 0) * Config.factor);
GL.Vertex2((float)(m_x + 1) * Config.factor, (float)(m_y - 1) * Config.factor);
GL.Vertex2((float)(m_x + 0) * Config.factor, (float)(m_y - 1) * Config.factor);
 
GL.End();

by the use of Vertex2 everything goes to Z = 0 (as it seems...)

and I want to look at it in the "normal" way, this means top down x to the right and y to the top.

So I created:

m_eye = new Vector3(0f,0f, 3f);
 
Matrix4 modelview = Matrix4.LookAt(m_eye, Vector3.Zero, Vector3.UnitY);

So far everything is fine.

but when I try to "zoom in" by changing the Z part of the m_eye, when I get to

m_eye = new Vector3(0f,0f, 1f);

the whole scene is gone...

Why?

with

m_eye = new Vector3(0f,0f, 1.1f);

and even

m_eye = new Vector3(0f,0f, 1.0000001f);

everything is still there, just bigger (as expected)

the scene is missing till

m_eye = new Vector3(0f,0f, -1f);

and with

m_eye = new Vector3(0f,0f, -1.000001f);

it works again, of course the scene is then looked from "below"... again as expected

Any idea why this is not working? I would have expected the scene to vanish for

m_eye = new Vector3(0f,0f, 0f);

because then the camera is at the same position as the tiles which have no depth...

bgrds and thanks,

AO


Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
siriusblack's picture

well, if you're wondering how matrix4.lookat works
the first argument is the location of your camera, so m_eye seems correct
the second argument is the point the camera centers on, so you'll want a location relative to your eye location or you'll always be focused on a single point in space
the third argument is to indicate what direction should be considered "up"

what's probably happening is you start at (0,0,0) looking at (0,0,0) with (0,1,0) being up
that just coincidentally happens to cause your camera to look at the location of the scene, which is for example in the direction (X,0,0);
then you move to (1,0,0), still looking at (0,0,0) with (0,1,0) being up
this instantly turns your camera to turn 180 degrees because the lookat target is behind the camera, so you're looking at (-X, 0, 0) instead of (X, 0, 0)

so in fact, if you wanted to always be looking at your object, you'll probably want to make the second argument something like

GL.Vertex3((float)(m_x + 0.5) * Config.factor, (float)(m_y - 0.5) * Config.factor, 0);

hope this helps

also make sure your scene is more than 1 away from the camera, so set their Z vector to like 20-30, so you actually have room to zoom in

bildsoe's picture

I'm having a similar problem, but in 3d.

Vector3 cameraPos = new Vector3(0, 20, 0);
Vector3 cameraTarget = new Vector3(0, 0, 0);
Vector3 cameraUp = new Vector3(0, 1, 0);

Matrix4 lookat = Matrix4.LookAt(cameraPos,cameraTarget,cameraUp);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref lookat);

When cameraPos has 0 for any of the values nothing is shown in the display:
Vector3 cameraPos = new Vector3(0, 20, 0);

But if I set it to:
Vector3 cameraPos = new Vector3(0.1f, 20f, 0.1f);

It works. Why can't the values be set to zero?

ao11's picture

Hello,

thank you for your explanation, however, I am still wondering why:

siriusblack wrote:

also make sure your scene is more than 1 away from the camera, so set their Z vector to like 20-30, so you actually have room to zoom in

This is exactly what I found out, but why is there this restriction and where does it come from. Is this a general OpenGL issue?

brgds,

AO

ao11's picture

Hi!

Maybe it's the same problem concerning the distance to your objects?

brgds,

AO

siriusblack's picture
ao11 wrote:

Hello,

thank you for your explanation, however, I am still wondering why:

siriusblack wrote:

also make sure your scene is more than 1 away from the camera, so set their Z vector to like 20-30, so you actually have room to zoom in

This is exactly what I found out, but why is there this restriction and where does it come from. Is this a general OpenGL issue?

brgds,

AO

it's not actually a restriction, but usually you'll have your projection matrix set up to have a near clipping plane of 1, so anything less than 1 away from the camera will be clipped
also if you have your object 1 or less away from the camera, you should imagine the measuring unit to be in centimeters and your object being a table, you're trying to look at it from less than 1 centimeter away(just taking an example), there's not much room to zoom in in that case, so you'll want to leave a bit more room

siriusblack's picture
bildsoe wrote:

I'm having a similar problem, but in 3d.

Vector3 cameraPos = new Vector3(0, 20, 0);
Vector3 cameraTarget = new Vector3(0, 0, 0);
Vector3 cameraUp = new Vector3(0, 1, 0);

Matrix4 lookat = Matrix4.LookAt(cameraPos,cameraTarget,cameraUp);
GL.MatrixMode(MatrixMode.Modelview);
GL.LoadMatrix(ref lookat);

When cameraPos has 0 for any of the values nothing is shown in the display:
Vector3 cameraPos = new Vector3(0, 20, 0);

But if I set it to:
Vector3 cameraPos = new Vector3(0.1f, 20f, 0.1f);

It works. Why can't the values be set to zero?

your problem is this:
your camera is positioned at 0,20,0, you're looking at 0,0,0, with the angle of rotation of the camera being 0,1,0, this means the camera has no clue what angle it should actually be in,
imagine your camera as a real camera, usually you'd keep the top of the camera facing up(0,1,0), but when you're shooting in that exact direction, what direction should the camera be facing in?

in other words, NEVER have the line cameraPos and cameraTarget be a line that, when normalised, is cameraUp