Several issues with attempt at 3D orthographic projection

Started by Alth2, October 23, 2021, 05:04:31

Previous topic - Next topic

Alth2

I am trying to add support for an orthographic camera but am at a roadblock. The projection matrix code seems to work somewhat but there are a few issues. Everything works when I use a perspective projection.

1. The cube I am rendering gets severely warped around the edges.
2. The aspect ratio seems to be disregarded even though I am multiplying the right and top floats by the aspect ratio. My code could be off but I can't figure out if it is.

What is rendered with a square window: https://i.gyazo.com/f108ee8bbb23df70f6665ca732f05725.png
What is rendered with a rectangular window: https://i.gyazo.com/da5612dfce8428453b0f941da0369bbc.png

Projection matrix:

public static Matrix4f createOrthographicProjectionMatrix(float left, float right, float bottom, float top, float near, float far) {
		Matrix4f matrix = new Matrix4f();
		matrix.identity();

		float aspect = Window.getWidth() / Window.getHeight();

		if (Window.getWidth() >= Window.getHeight()) {
			left = left * aspect;
			right = right * aspect;
		} else {
			bottom = bottom / aspect;
			top = top / aspect;
		}

		matrix.set(0, 0, 2 / (right - left));
		matrix.set(0, 1, 0);
		matrix.set(0, 2, 0);
		matrix.set(0, 3, -(left + right) / (left - right));

		matrix.set(1, 0, 0);
		matrix.set(1, 1, 2 / (top - bottom));
		matrix.set(1, 2, 0);
		matrix.set(1, 3, -(bottom + top) / (top - bottom));

		matrix.set(2, 0, 0);
		matrix.set(2, 1, 0);
		matrix.set(2, 2, 2 / (far - near));
		matrix.set(2, 3, -(far + near) / (far - near));

		matrix.set(3, 0, 0);
		matrix.set(3, 1, 0);
		matrix.set(3, 2, 0);
		matrix.set(3, 3, 1);

		return matrix;
	}


Transformation matrix:

public static Matrix4f createTransformationMatrix3(Vector3f translation, Quaternionf rotation, Vector3f scale) {
		Matrix4f matrix = new Matrix4f();
		matrix.identity();
		matrix.translate(translation, matrix);
		matrix.rotate(rotation, matrix);
		//matrix.rotate((float) Math.toRadians(0),1,0,0, matrix);
		//matrix.rotate((float) Math.toRadians(0),0,1,0, matrix);
		//matrix.rotate((float) Math.toRadians(0),0,0,1, matrix);
		matrix.scale(scale, matrix);

		return matrix;
	}


View matrix:

public static Matrix4f createViewMatrix(Camera camera) {
		Matrix4f matrix = new Matrix4f();
		matrix.identity();
		matrix.rotate((float) Math.toRadians(camera.getRotation().x), 1, 0, 0, matrix);
		matrix.rotate((float) Math.toRadians(camera.getRotation().y), 0, 1, 0, matrix);
		//matrix.rotate(camera.getTransform().getRotation(), matrix);
		Vector3f position = camera.getPosition();
		Vector3f negativePosition = new Vector3f(-position.x, -position.y, -position.z);
		matrix.translate(negativePosition, matrix);

		return matrix;
	}


Fragment shader:

#version 400 core

in vec2 pass_textureCoordinates;
in vec3 surfaceNormal;
in vec3 toLightVector;
in vec3 toCameraVector;

out vec4 out_Color;

uniform sampler2D modelTexture;
uniform vec3 lightColour;
uniform float roughness;
uniform float specularity;

void main(void) {

    vec3 unitNormal = normalize(surfaceNormal);
    vec3 unitLightVector = normalize(toLightVector);

    float normalDot = dot(unitNormal, unitLightVector);
    float brightness = max(normalDot, 0.1);

    vec3 diffuse = brightness * lightColour;

    vec3 unitToCameraVector = normalize(toCameraVector);
    vec3 lightDirection = -unitLightVector;
    vec3 reflectedLightDirection = reflect(lightDirection, unitNormal);

    float specularValue = dot(reflectedLightDirection, unitToCameraVector);
    specularValue = max(specularValue, 0.0);
    float roughnessValue = pow(specularValue, roughness);
    vec3 finalSpecular = roughnessValue * specularity * lightColour;

    out_Color = vec4(diffuse, 1.0) * texture(modelTexture, pass_textureCoordinates) + vec4(finalSpecular, 1.0);
}


Vertex shader:

#version 400 core

in vec3 position;
in vec2 textureCoordinates;
in vec3 normal;

out vec2 pass_textureCoordinates;
out vec3 surfaceNormal;
out vec3 toLightVector;
out vec3 toCameraVector;

uniform mat4 transformationMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform vec3 lightPosition;

void main(void) {

    vec4 worldPosition = transformationMatrix * vec4(position, 1.0);
    gl_Position = projectionMatrix * viewMatrix * worldPosition;
    pass_textureCoordinates = textureCoordinates;

    surfaceNormal = (transformationMatrix * vec4(normal, 0.0)).xyz;
    toLightVector = lightPosition - worldPosition.xyz;
    toCameraVector = (inverse(viewMatrix) * vec4(0.0, 0.0, 0.0, 1.0)).xyz - worldPosition.xyz;
}

Alth2

So the ortho matrix was wrong, ended up just copying glOrtho matrix data.