]> git.tdb.fi Git - libs/gl.git/commitdiff
Refactor projection matrix handling
authorMikko Rasa <tdb@tdb.fi>
Tue, 14 Dec 2021 11:21:25 +0000 (13:21 +0200)
committerMikko Rasa <tdb@tdb.fi>
Tue, 14 Dec 2021 11:28:56 +0000 (13:28 +0200)
Projection matrices in C++ side now always produce a depth range of 0 to
1 for the NDC Z coordinate.  Shaders will convert it to -1 to 1 when
targeting OpenGL.

Incidentally, the AmbientOcclusion effect's shaders were already written
as if the depth range was 0 to 1, so the effect was actually slightly
incorrect before this.

source/backends/opengl/camera_backend.h [deleted file]
source/backends/vulkan/camera_backend.cpp [deleted file]
source/backends/vulkan/camera_backend.h [deleted file]
source/core/matrix.cpp
source/effects/shadowmap.cpp
source/glsl/compiler.cpp
source/glsl/finalize.cpp
source/glsl/finalize.h
source/render/camera.cpp
source/render/camera.h

diff --git a/source/backends/opengl/camera_backend.h b/source/backends/opengl/camera_backend.h
deleted file mode 100644 (file)
index 574919e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef MSP_GL_CAMERA_BACKEND_H_
-#define MSP_GL_CAMERA_BACKEND_H_
-
-namespace Msp {
-namespace GL {
-
-class Matrix;
-
-class OpenGLCamera
-{
-protected:
-       static void adjust_projection_matrix(Matrix &) { }
-};
-
-using CameraBackend = OpenGLCamera;
-
-} // namespace GL
-} // namespace Msp
-
-#endif
diff --git a/source/backends/vulkan/camera_backend.cpp b/source/backends/vulkan/camera_backend.cpp
deleted file mode 100644 (file)
index 10e294f..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-#include "camera_backend.h"
-#include "matrix.h"
-
-namespace Msp {
-namespace GL {
-
-void VulkanCamera::adjust_projection_matrix(Matrix &proj_matrix)
-{
-       Matrix adjust;
-       adjust(2, 2) = 0.5f;
-       adjust(2, 3) = 0.5f;
-       proj_matrix = adjust*proj_matrix;
-}
-
-} // namespace GL
-} // namespace Msp
diff --git a/source/backends/vulkan/camera_backend.h b/source/backends/vulkan/camera_backend.h
deleted file mode 100644 (file)
index e22fdb5..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-#ifndef MSP_GL_CAMERA_BACKEND_H_
-#define MSP_GL_CAMERA_BACKEND_H_
-
-namespace Msp {
-namespace GL {
-
-class Matrix;
-
-class VulkanCamera
-{
-protected:
-       static void adjust_projection_matrix(Matrix &);
-};
-
-using CameraBackend = VulkanCamera;
-
-} // namespace GL
-} // namespace Msp
-
-#endif
index 0eb9e916aac6a56cffcc4de00ec08d35edc77812..54dbdff6ca0c2355105a523c54352c543bb13458 100644 (file)
@@ -65,10 +65,10 @@ Matrix Matrix::ortho(float l, float r, float b, float t, float n, float f)
        Matrix result;
        result(0, 0) = 2/(r-l);
        result(1, 1) = 2/(t-b);
-       result(2, 2) = -2/(f-n);
+       result(2, 2) = -1/(f-n);
        result(0, 3) = -(r+l)/(r-l);
        result(1, 3) = -(t+b)/(t-b);
-       result(2, 3) = -(f+n)/(f-n);
+       result(2, 3) = 0.5f-0.5f*(f+n)/(f-n);
        return result;
 }
 
@@ -97,9 +97,9 @@ Matrix Matrix::frustum(float l, float r, float b, float t, float n, float f)
        result(1, 1) = 2*n/(t-b);
        result(0, 2) = (r+l)/(r-l);
        result(1, 2) = (t+b)/(t-b);
-       result(2, 2) = -(f+n)/(f-n);
+       result(2, 2) = -f/(f-n);
        result(3, 2) = -1;
-       result(2, 3) = -2*f*n/(f-n);
+       result(2, 3) = -f*n/(f-n);
        result(3, 3) = 0;
        return result;
 }
index 9aee4907a1cd5eb174bfd30d32f0bbd38c32f388..123cae274bb698327c476dfa382f69e0d266487b 100644 (file)
@@ -196,7 +196,7 @@ void ShadowMap::setup_frame(Renderer &renderer)
                {
                        float distance = (sqrt(2.0f/3.0f)-sqrt(3.0f/8.0f))*2.0f;
                        float bias = depth_bias*2.0f/(distance*l.region.width);
-                       shdata.uniform(base+".bias", -1001.0f/999.0f, 1.0f-bias);
+                       shdata.uniform(base+".bias", views[l.view_index].camera.get_projection_matrix()(2, 2), 1.0f-bias);
                }
        }
 
@@ -219,7 +219,7 @@ void ShadowMap::setup_frame(Renderer &renderer)
                        v.camera.set_depth_clip(radius/1000.0f, radius);
                }
 
-               Matrix to_texcoord = Matrix().translate(Vector3(0.5f, 0.5f, 0.5f)).scale(0.5f);
+               Matrix to_texcoord = Matrix().translate(Vector3(0.5f, 0.5f, 0.0f)).scale(Vector3(0.5f, 0.5f, 1.0f));
                shadow_matrices.push_back(to_texcoord*v.camera.get_projection_matrix()*v.camera.get_view_matrix());
        }
 
index f1ab6d088e4e1bdedd5d4188685ef2f6a55f02e0..4c8c1d03d893d277395b2f64b5def34aa7e55168 100644 (file)
@@ -93,6 +93,11 @@ void Compiler::compile(Mode mode)
                for(Stage &s: module->stages)
                        ConstantSpecializer().apply(s, spec_values);
        }
+       if(mode==PROGRAM)
+       {
+               for(Stage &s: module->stages)
+                       DepthRangeConverter().apply(s, features);
+       }
        for(auto i=module->stages.begin(); i!=module->stages.end(); )
        {
                OptimizeResult result = optimize(*i);
index 29eef60fb3342d12c31374441ed7a076d343ea2c..fb136e33c7dbc79fd03706ba6ef3450d4906fe5c 100644 (file)
@@ -239,6 +239,56 @@ void LocationAllocator::visit(VariableDeclaration &var)
 }
 
 
+void DepthRangeConverter::apply(Stage &stage, const Features &features)
+{
+       if(stage.type!=Stage::VERTEX || features.target_api==VULKAN)
+               return;
+
+       stage.content.visit(*this);
+}
+
+void DepthRangeConverter::visit(FunctionDeclaration &func)
+{
+       if(func.definition==&func && func.name=="main")
+       {
+               VariableReference *position = new VariableReference;
+               position->name = "gl_Position";
+
+               MemberAccess *z = new MemberAccess;
+               z->left = position;
+               z->member = "z";
+
+               Literal *scale = new Literal;
+               scale->token = "2.0";
+               scale->value = 2.0f;
+
+               BinaryExpression *multiply = new BinaryExpression;
+               multiply->oper = &Operator::get_operator("*", Operator::BINARY);
+               multiply->left = z;
+               multiply->right = scale;
+
+               MemberAccess *w = new MemberAccess;
+               w->left = position->clone();
+               w->member = "w";
+
+               BinaryExpression *subtract = new BinaryExpression;
+               subtract->oper = &Operator::get_operator("-", Operator::BINARY);
+               subtract->left = multiply;
+               subtract->right = w;
+
+               Assignment *assign = new Assignment;
+               assign->oper = &Operator::get_operator("=", Operator::BINARY);
+               assign->left = z->clone();
+               assign->right = subtract;
+
+               ExpressionStatement *statement = new ExpressionStatement;
+               statement->expression = assign;
+
+               func.body.body.push_back(statement);
+       }
+}
+
+
 void PrecisionConverter::apply(Stage &s)
 {
        stage = &s;
index 79ba54b81b027c8b16743e0f1281b3e961611319..6e96c65eaecb46c0b7d04aaae3027cb063d7bbdf 100644 (file)
@@ -56,6 +56,18 @@ private:
        virtual void visit(FunctionDeclaration &) { }
 };
 
+/**
+Converts the output depth range to match expectations of the target API.
+*/
+class DepthRangeConverter: private TraversingVisitor
+{
+public:
+       void apply(Stage &, const Features &);
+
+private:
+       virtual void visit(FunctionDeclaration &);
+};
+
 /** Generates default precision declarations or removes precision declarations
 according to the requirements of the target API. */
 class PrecisionConverter: private TraversingVisitor
index 9ecb79cd80643d4ce4e4d77f045d4354aebb37af..3ace92b9ecb7166de54fa20b33f07c943997dae1 100644 (file)
@@ -139,8 +139,6 @@ void Camera::update_projection_matrix()
                proj_matrix = Matrix::ortho(left, right, bottom, top, clip_near, clip_far);
        proj_matrix = Matrix::rotation(rotate, Vector3(0, 0, 1))*proj_matrix;
 
-       adjust_projection_matrix(proj_matrix);
-
        shdata.uniform("clip_eye_matrix", proj_matrix);
        shdata.uniform("eye_clip_matrix", invert(proj_matrix));
 }
index c713f7e49608c500f572be8e28b853cfdabca050..cb9b4ce19423e36cdf126303a6e0b197eeb2ff69 100644 (file)
@@ -2,7 +2,6 @@
 #define MSP_GL_CAMERA_H_
 
 #include <msp/datafile/objectloader.h>
-#include "camera_backend.h"
 #include "placeable.h"
 #include "programdata.h"
 
@@ -23,7 +22,7 @@ YZ plane of eye space is aligned to the plane formed by the look and up
 directions.  Setting the up direction to the opposite of gravity direction is
 an easy way to keep the camera upright.
 */
-class Camera: public CameraBackend, public Placeable
+class Camera: public Placeable
 {
 public:
        class Loader: public DataFile::ObjectLoader<Camera>