Public Group

# OpenGL 4.2 LookAt matrix only works with -z value for eye position

## Recommended Posts

I am trying to understand the model view projection matrix usage since a few days now, and still have some issues i just don't understand. I am using OpenTK (.NET OpenGL wrapper library).

Here is a "working" setup: (it displays the triangle)

// ### setup OpenGL ###
// not sure if this is important; this is basically just so that i can render only in part of a screen because the OpenGL thing is part of a larger project
// it's included just in case...
GL.Enable(EnableCap.ScissorTest);

GL.Viewport(0, 0, (int)windowPosition.Width, (int)windowPosition.Height);
GL.Scissor(x, y, width, height);

// maybe more important
GL.Enable(EnableCap.DepthTest);
GL.Disable(EnableCap.CullFace); // should be default value, but i am not sure if it is

// ### rendering ###

var projection = Matrix4.CreateOrthographic(3, 3, 0.001f, 50);

var view = Matrix4.LookAt(
new Vector3(0.5f, 0.5f, -2),
new Vector3(0.5f, 0.5f, 0),
new Vector3(0, 1, 0));

var viewProjectionMatrix = projection * view;

// set uniforms...

var modelMatrix = ...
// values are: (scaling by factor 2)
// [2 0 0 0]
// [0 2 0 0]
// [0 0 2 0]
// [0 0 0 1]

// triangle vertices
var data = new float[]
{
0, 0, 0,
1, 0, 0,
0, 1, 0
};

#version 420

layout(location = 0) in vec3 position;

uniform mat4 viewProjection;
uniform mat4 model;

out vec3 outColor;

void main()
{
gl_Position = viewProjection * model * vec4(position, 1);
outColor = vec3(1,1,1);
}


As I said this setup works. As far as I understand this will create a "camera" placed further down the z axis (which in open gl normally means farther behind), since positive z values point to the viewer by default.

The problem:

To keep the usual OpenGL setup I would like the the camera eye to placed at new Vector3(0.5f, 0.5f, 2) instead of new Vector3(0.5f, 0.5f, -2), but for some reason I can't see the triangle anymore. I drew it on paper and don't get it. As you can see FaceCulling is explicitly disabled, so this can't be the reason.

Maybe I am misunderstanding something.

And just in case the problem is the the Matrix4.LookAt function, here is the matrix it creates (no idea if this makes sense)

with eye-z = -2

view: (eye-z = -2)
(-1, 0, 0, 0)
(0, 1, 0, 0)
(0, 0, -1, 0)
(0.5, -0.5, -2, 1)

projection:
(0.6666667, 0, 0, 0)
(0, 0.6666667, 0, 0)
(0, 0, -0.0400008, 0)
(0, 0, -1.00004, 1)

projection * view:
(-0.6666667, 0, 0, 0)
(0, 0.6666667, 0, 0)
(0, 0, 0.0400008, 0)
(0.5, -0.5, -0.9999601, 1)

view: (eye-z = 2)
(1, 0, 0, 0)
(0, 1, 0, 0)
(0, 0, 1, 0)
(-0.5, -0.5, -2, 1)

projection:
(0.6666667, 0, 0, 0)
(0, 0.6666667, 0, 0)
(0, 0, -0.0400008, 0)
(0, 0, -1.00004, 1)

projection * view:
(0.6666667, 0, 0, 0)
(0, 0.6666667, 0, 0)
(0, 0, -0.0400008, 0)
(-0.5, -0.5, -3.00004, 1)

##### Share on other sites

Your orthographic matrix looks strange, or has OpenTK a special version ?

Change it to left, right, bottom, up, e.g. 0, 640, 0, 480.

Scrub. It has. Sorry for the nonsense.

Aand: coordinate spaces.

Edited by Green_Baron

##### Share on other sites

This is what OpenTK does

/// <summary>Creates an orthographic projection matrix.</summary>
/// <param name="width">The width of the projection volume.</param>
/// <param name="height">The height of the projection volume.</param>
/// <param name="zNear">The near edge of the projection volume.</param>
/// <param name="zFar">The far edge of the projection volume.</param>
/// <rereturns>The resulting Matrix4 instance.</rereturns>
public static Matrix4 CreateOrthographic(
float width,
float height,
float zNear,
float zFar)
{
Matrix4 result;
Matrix4.CreateOrthographicOffCenter((float) (-(double) width / 2.0), width / 2f, (float) (-(double) height / 2.0), height / 2f, zNear, zFar, out result);
return result;
}

/// <summary>Creates an orthographic projection matrix.</summary>
/// <param name="left">The left edge of the projection volume.</param>
/// <param name="right">The right edge of the projection volume.</param>
/// <param name="bottom">The bottom edge of the projection volume.</param>
/// <param name="top">The top edge of the projection volume.</param>
/// <param name="zNear">The near edge of the projection volume.</param>
/// <param name="zFar">The far edge of the projection volume.</param>
/// <param name="result">The resulting Matrix4 instance.</param>
public static void CreateOrthographicOffCenter(
float left,
float right,
float bottom,
float top,
float zNear,
float zFar,
out Matrix4 result)
{
result = Matrix4.Identity;
float num1 = (float) (1.0 / ((double) right - (double) left));
float num2 = (float) (1.0 / ((double) top - (double) bottom));
float num3 = (float) (1.0 / ((double) zFar - (double) zNear));
result.Row0.X = 2f * num1;
result.Row1.Y = 2f * num2;
result.Row2.Z = -2f * num3;
result.Row3.X = (float) -((double) right + (double) left) * num1;
result.Row3.Y = (float) -((double) top + (double) bottom) * num2;
result.Row3.Z = (float) -((double) zFar + (double) zNear) * num3;
}

Edited by DBisar

##### Share on other sites

Yeah, my fault. I just looked it up ... looks right.

You can disable scissor and depth test. They are not needed here.

Try setting the camera at 0, 0, -2 and look at 0,0,0. I think that's where your triangle is ...

Edited by Green_Baron

##### Share on other sites

Scissor is just to render it only in part of the screen (actually this is a control with it's own OpenGL context as part of a usually 2d library; didn't want to make the question to complicated).

@Green_Baron: yes this works. Just as the setup above, doesn't really solve my problem. I don't know what is strange to me is, that the values that work for eye z coordinate are from  < 0 until -2 all other values do not render anything. When the value becomes 0 or less the triangle suddenly disappears and when the value become ~ greater 2 the same. It seems like some kind of clipping takes place...

By the way, my fragment shader:

#version 420

in vec3 outColor;
out vec4 fragmentColor;

void main()
{
fragmentColor = vec4(outColor, 1);
}

Disabled DepthTest and ScissorTest does not change anything...

##### Share on other sites

What makes me wondering the most now is the this:

target for both = 0, 0, 0

eye = 0,0,-1

projection:
(0.6666667, 0, 0, 0)
(0, 0.6666667, 0, 0)
(0, 0, -0.0400008, 0)
(0, 0, -1.00004, 1)
view:
(-1, 0, 0, 0)
(0, 1, 0, 0)
(0, 0, -1, 0)
(0, 0, -1, 1)
Vector 0
(0, 0, 0)
(0, 0, 0, 1) // is the vector multiplied with the view matrix
(0, 0, 0, 1) // is the vector multiplied with the view and projection matrix (means: value = proj * view * vec)
Vector 1
(1, 0, 0)
(-1, 0, 0, 1)
(-0.6666667, 0, 0, 1)
Vector 2
(0, 1, 0)
(0, 1, 0, 1)
(0, 0.6666667, 0, 1)

Shows the triangle. If i set eye to:

eye = 0, 0, -2.1f

projection:
(0.6666667, 0, 0, 0)
(0, 0.6666667, 0, 0)
(0, 0, -0.0400008, 0)
(0, 0, -1.00004, 1)
view:
(-1, 0, 0, 0)
(0, 1, 0, 0)
(0, 0, -1, 0)
(0, 0, -2.1, 1)
Vector 0
(0, 0, 0)
(0, 0, 0, 1)
(0, 0, 0, 1)
Vector 1
(1, 0, 0)
(-1, 0, 0, 1)
(-0.6666667, 0, 0, 1)
Vector 2
(0, 1, 0)
(0, 1, 0, 1)
(0, 0.6666667, 0, 1)

So not a thing different but still this leads to not displaying anything.

Now i am just more confused...

Code used to generate the debug output:

var va = new[] {new Vector3(0, 0, 0), new Vector3(1, 0, 0), new Vector3(0, 1, 0)};

Console.WriteLine("projection:\n" + projection);
Console.WriteLine("view:\n" + view);

for (int i = 0; i < va.Length; i++)
{
Console.WriteLine("Vector " + i);
Console.WriteLine(va[i]);
Console.WriteLine(view * new Vector4(va[i], 1));
Console.WriteLine(projection * view * new Vector4(va[i], 1));
}

How I set the uniform matrices for the shader:

GL.UniformMatrix4(Id, false, ref value);

which shouldn't be the problem either, because for rotating the triangle itself it just works fine.

##### Share on other sites

So, you found the triangle at 0,0,0 ?

Clipping takes place at the near and far planes and at <0 and >3 in x and y ...

##### Share on other sites

with

Matrix4.CreateOrthographic(3, 3, 0.001f, 50);

means width and height = 3, zNear = 0.001f, zFar = 50

Do i have to tell OpenGL somehow specifically were the clipping planes are?

##### Share on other sites

How about your model matrix uniform...is that in a garbage state because it's commented out client side? What does that log?

##### Share on other sites
15 minutes ago, DBisar said:

Do i have to tell OpenGL somehow specifically were the clipping planes are?

No. That's hardcoded in the pipeline. There are margins that be set, but they don't play a role here.

11 minutes ago, GoliathForge said:

How about your model matrix uniform...is that in a garbage state because it's commented out client side? What does that log?

If it is not set it should be an identity matrix.

Edit: but good point, for clarity it should be constructed with = mat4( 1.0f );

'Nother thing, do you actually set the view projection matrix ? What is 'value' ?

Edited by Green_Baron

• ### Game Developer Survey

We are looking for qualified game developers to participate in a 10-minute online survey. Qualified participants will be offered a \$15 incentive for your time and insights. Click here to start!

• 11
• 15
• 21
• 26
• 11