Jump to content
  • Advertisement
DBisar

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 ###
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

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



// ### vertex shader ###
Vertex Shader:

#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 this post


Link to post
Share on other sites
Advertisement

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.

I had to read it over and again 🙂

Edited by Green_Baron

Share this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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 this post


Link to post
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

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!