From bdf62286794e31f05fde8beb9a7152c13373e5e4 Mon Sep 17 00:00:00 2001 From: JackCarterSmith Date: Sat, 28 Dec 2024 23:16:26 +0100 Subject: [PATCH] Horizon level computation final --- Engine/Graphics/3DRenderer.cpp | 32 +++++++++++++------------------- Engine/Graphics/Camera.cpp | 1 + Engine/Graphics/Camera.hpp | 4 +++- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/Engine/Graphics/3DRenderer.cpp b/Engine/Graphics/3DRenderer.cpp index bb687d3..db5ef86 100644 --- a/Engine/Graphics/3DRenderer.cpp +++ b/Engine/Graphics/3DRenderer.cpp @@ -58,7 +58,7 @@ Graphic3DRenderer::~Graphic3DRenderer() {} void Graphic3DRenderer::SetRTSize(unsigned int w, unsigned int h) { mRTSize.x = w; mRTSize.y = h; - mMainCamera->SetFrustrum(75.0f, mRTSize.x/mRTSize.y, 1.0f, 100.f); + mMainCamera->SetFrustrum(90.0f, mRTSize.x/mRTSize.y, 1.0f, 100.f); } void Graphic3DRenderer::UpdateCamera(CAMERA_MOVE type, const float value) { @@ -231,29 +231,23 @@ void Graphic3DRenderer::UpdateInternalTestObjects() { mRenderList[2]->SetRotation(thetaAngle3, 0.f, thetaAngle3 * 0.5f); mRenderList[3]->SetRotation(0.f, thetaAngle, 0.f); } -#include + // Compute the screen ratio between the ground and the sky (aka. Line of Horizon) inline float Graphic3DRenderer::ComputeSGRatio() { // FoV angle for Y axis is recovered using frustrum FoV and apply RT screen ratio to it - //const double fovYAngleDiv2 = M3D_Deg2Rad(mMainCamera->GetFoV() * mRTSize.y / mRTSize.x) * 0.5f; - const double fovYAngle = M3D_Deg2Rad(mMainCamera->GetFoV()) * mRTSize.y / mRTSize.x; + const float fovYAngleDiv2 = M3D_Deg2Rad(mMainCamera->GetFoV()) * 0.5f; // Get the camera pitch angle over camera FoV ratio - //const float theta = M3D_ScalarASin(-mMainCamera->GetLook3f().y) * (fovYAngleDiv2 + 0.2047198f) / M3D_PIDIV2; - const float theta = M3D_ScalarASin(-mMainCamera->GetLook3f().y); + const float theta = M3D_ScalarASinEst(-mMainCamera->GetLook3f().y); + // Get the camera altitude from the ground + const float altitude = mMainCamera->GetPos3f().y; - // Simple approach, real (infinite) horizon (w/o camera height and far screen calculation) - double sgRatio = 0.5f + std::tan(((theta / M3D_PI) / fovYAngle) * M3D_PIDIV4); - std::cout << (theta / M3D_PI) << ' ' << fovYAngle << ' ' << sgRatio << std::endl; - // Finite ground (to far plan), camera height impact the ground "level" -- KEEP FOR FURTHER USE - /*double sgRatio = -(mMainCamera->GetPos3f().y * 0.1f * M3D_ScalarCos(fovYAngleDiv2) - 101.f * M3D_ScalarSin(fovYAngleDiv2 + theta)) - / (2.f * 101.f * M3D_ScalarSin(fovYAngleDiv2) * M3D_ScalarCos(theta)); - std::cout << fovYAngleDiv2 << ' ' << theta << ' ' << sgRatio << std::endl;*/ - /*double p0 = 101.f / M3D_ScalarCos(fovYAngleDiv2); - double pf = mMainCamera->GetPos3f().y * 0.1f / M3D_ScalarSin(theta+fovYAngleDiv2); - double gh = (std::abs(p0 - pf) * M3D_ScalarSin(theta+fovYAngleDiv2)) / M3D_ScalarCos(theta); - double sh = 2.f * 101.f * std::tan(fovYAngleDiv2); - double sgRatio = gh / sh; - std::cout << fovYAngleDiv2 << ' ' << theta << " p0:" << p0 << " pf:" << pf << " gh:" << gh << " sh:" << sh << ' ' << sgRatio << std::endl;*/ + // Ground/Sky screen ratio calculation using "simple" trigonometric properties of the + // pinhole (frustrum) camera model. + // The triangle made by the ground plane intersection with the frustum. This intersection + // cross the far plane at some point. Instead of computing the coordinate of the point, we + // directly use the far plane length to get the corresponding ratio for the screen. + double sgRatio = -(altitude * M3D_ScalarCosEst(fovYAngleDiv2) - mMainCamera->GetFarZ() * M3D_ScalarSinEst(fovYAngleDiv2 + theta)) + / (2.f * mMainCamera->GetFarZ() * M3D_ScalarSinEst(fovYAngleDiv2) * M3D_ScalarCosEst(theta)); // Clamp if (sgRatio > 1.f) diff --git a/Engine/Graphics/Camera.cpp b/Engine/Graphics/Camera.cpp index 4808206..3cd6a2c 100644 --- a/Engine/Graphics/Camera.cpp +++ b/Engine/Graphics/Camera.cpp @@ -8,6 +8,7 @@ Camera::Camera() { void Camera::SetFrustrum(float fov, float r, float zn, float zf) { //if (!frameDirty) this->fov = fov; + this->zf = zf; M3D_MATRIX pMat = M3D_TransformMatrixFrustrumFovLH(M3D_Deg2Rad(fov), r, zn, zf); M3D_V4StoreF4x4(&mProjMat, pMat); } diff --git a/Engine/Graphics/Camera.hpp b/Engine/Graphics/Camera.hpp index 2d01b3f..6d83e61 100644 --- a/Engine/Graphics/Camera.hpp +++ b/Engine/Graphics/Camera.hpp @@ -14,6 +14,7 @@ public: Camera& operator= (Camera const&) = delete; float GetFoV() const { return fov; } + float GetFarZ() const { return zf; } M3D_VECTOR GetPos() const { return M3D_V4LoadF3(&mPos); } M3D_F3 GetPos3f() const { return mPos; } M3D_VECTOR GetLook() const { return M3D_V4LoadF3(&mLook); } @@ -39,7 +40,8 @@ public: void Yaw(float angle); private: - float fov; + float fov; // It's the Y-FoV! + float zf; M3D_F4X4 mProjMat = M3D_MIdentity4x4(); M3D_F4X4 mViewMat = M3D_MIdentity4x4();