Hello,

So I figured out the MVP matrix thing and I get things on the screen all well and good.

I searched for this additional piece of information but I didn’t find it as of yet.

The question is now each object in question has their own rotation, translation, scaling, etc. separate from the MVP for the screen.

So I know I will need another uniform in my vertex shader code below but how do I alter the near-last line to incorporate the “ObjectOffsetMatrix” which contains the translation, rotation, and scale?

Thank you for your time.

```
#version 140
#extension GL_ARB_explicit_attrib_location : require
in vec4 vPosition;
in vec3 vNormal;
in vec2 vUV;
out vec3 SurfaceNormal;
uniform mat4 ModelViewProjectionMatrix;
uniform mat4 ObjectOffsetMatrix;
uniform mat3 NormalMatrix;
void main () {
SurfaceNormal = normalize(NormalMatrix * vNormal);
gl_Position = ModelViewProjectionMatrix * vPosition;
}
```

Why don’t you just use a modelview matrix and a normal matrix per object and a seperate projection matrix?

OK, so something like this?

```
#version 140
#extension GL_ARB_explicit_attrib_location : require
in vec4 vPosition;
in vec3 vNormal;
in vec2 vUV;
out vec3 SurfaceNormal;
//
//uniform mat4 ModelViewProjectionMatrix;
//
//
//uniform mat4 ObjectOffsetMatrix;
//
uniform vec4 ObjectRotationVector; -> Calculated CPU Side
uniform vec4 ObjectTranslationVector; -> Calculated CPU Side
uniform vec4 ObjectScalingVector; -> Calculated CPU Side
uniform mat4 ProjectionMatrix; -> Calculated CPU Side
uniform mat4 ViewMatrix; -> Calculated CPU Side?
uniform mat3 NormalMatrix; -> Where would this be calculated? CPU side?
void main () {
vec4 vectorPosition;
SurfaceNormal = normalize(NormalMatrix * vNormal);
vectorPosition = ObjectScalingVector * ObjectRotationVector * ObjectTranslationVector * vPosition;
gl_Position = ProjectionMatrix * ViewMatrix * vectorPosition;
}
```

Something like that.

The way I do transformations is pretty much like this:

```
....
uniform mat4 m_modelview;
uniform mat3 m_normal;
uniform mat4 m_projection;
....
in vec4 v_position;
in vec3 v_normal;
....
void main( )
{
....
vec4 P = m_modelview * v_position;
vec3 N = normalize( m_normal * v_normal );
....
/* use P and N for whatever, tangents and bitangents can be transformed similar to v_normal */
....
gl_Position = m_projection * P;
}
```

Used in the shader:

[ul]

[li]m_modelview transforms from models space into viewspace[/li][li]m_normal transforms model space normal to view space normals[/li][li]m_projection contains the camera projection matrix[/li][/ul]

m_modelview is calculated per object on the CPU using double precision arithmetic as the result of:

m_modelview = m_worldview * m_modelworld

m_modelview is sent to the shader as floats.

m_normal is computed on the CPU as this: m_normal = transpose( inverse( mat3( m_modelview ) ) )

The reason to do this with double values on the CPU:

[ul]

[li] Think of a scenario where the camera is looking at an object close to it.[/li][li]Both the camera and the object can be very far from the world space origin.[/li][li] The object has a world space position stored.[/li][li] The camera has a world space position stored.[/li][li]Transforming from model space to world space first, yields a matrix with large values in the last column.[/li][li]Same goes for transforming from world space to view space.[/li][li]Can result in floating point inaccuracies, altough the object is actually close to the camera.[/li][li]Transforming from world space to view space in one step yields a matrix with small values, as the object is close to the camera.[/li][/ul]

Of course, you could combine the m_modelview with the m_projection like this:

MVP = m_projection * m_modelview

and only send the MVP matrix to the shader.