From 6e7b980096e8d48da57c278c6e3c66f0e9b71a2b Mon Sep 17 00:00:00 2001 From: JackCarterSmith Date: Sat, 14 Dec 2024 19:01:28 +0100 Subject: [PATCH] Experiment on simplified LoH Another try of camera model for horizon --- Engine/Graphics/3DRenderer.cpp | 49 ++++++++++++++++++++++------------ 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/Engine/Graphics/3DRenderer.cpp b/Engine/Graphics/3DRenderer.cpp index a5f8ac6..bb687d3 100644 --- a/Engine/Graphics/3DRenderer.cpp +++ b/Engine/Graphics/3DRenderer.cpp @@ -31,14 +31,12 @@ static bool VertexClipTest(M3D_F4& V, sf::Vector2f& RTsize, float gb_factor); Graphic3DRenderer::Graphic3DRenderer() { - mRTSize = {1280.f, 324.f}; - if (mMainCamera == nullptr) { mMainCamera = std::make_unique(); mMainCamera->SetPosition(0.0f, 1.5f, -8.0f); - mMainCamera->SetFrustrum(75.0f, mRTSize.x/mRTSize.y, 1.0f, 100.f); - mMainCamera->UpdateCamView(); } + SetRTSize(1280.f, 324.f); + mMainCamera->UpdateCamView(); // Fill world object list to render mRenderList.clear(); @@ -60,7 +58,7 @@ Graphic3DRenderer::~Graphic3DRenderer() {} void Graphic3DRenderer::SetRTSize(unsigned int w, unsigned int h) { mRTSize.x = w; mRTSize.y = h; - mMainCamera->SetFrustrum(90.0f, mRTSize.x/mRTSize.y, 1.0f, 100.f); + mMainCamera->SetFrustrum(75.0f, mRTSize.x/mRTSize.y, 1.0f, 100.f); } void Graphic3DRenderer::UpdateCamera(CAMERA_MOVE type, const float value) { @@ -126,10 +124,10 @@ void Graphic3DRenderer::Draw(sf::RenderTexture& context) { const float sgRatio = ComputeSGRatio(); sf::RectangleShape gndRect; if (mMainCamera->GetPos3f().y >= 0) { - gndRect.setSize(sf::Vector2f(1280, mRTSize.y * (1.f - sgRatio))); - gndRect.setPosition(sf::Vector2f(0, mRTSize.y * sgRatio)); + gndRect.setSize(sf::Vector2f(mRTSize.x, mRTSize.y * sgRatio)); + gndRect.setPosition(sf::Vector2f(0, mRTSize.y * (1.f - sgRatio))); } else { - gndRect.setSize(sf::Vector2f(1280, mRTSize.y * sgRatio)); + gndRect.setSize(sf::Vector2f(mRTSize.x, mRTSize.y * (1.f - sgRatio))); gndRect.setPosition(sf::Vector2f(0, 0)); } gndRect.setFillColor(sf::Color::Green); @@ -233,20 +231,37 @@ 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 float fovYAngle = M3D_Deg2Rad(mMainCamera->GetFoV() * (mRTSize.y/mRTSize.x)); + //const double fovYAngleDiv2 = M3D_Deg2Rad(mMainCamera->GetFoV() * mRTSize.y / mRTSize.x) * 0.5f; + const double fovYAngle = M3D_Deg2Rad(mMainCamera->GetFoV()) * mRTSize.y / mRTSize.x; // Get the camera pitch angle over camera FoV ratio - float sgRatio = M3D_ScalarASinEst(mMainCamera->GetLook3f().y) / fovYAngle; + //const float theta = M3D_ScalarASin(-mMainCamera->GetLook3f().y) * (fovYAngleDiv2 + 0.2047198f) / M3D_PIDIV2; + const float theta = M3D_ScalarASin(-mMainCamera->GetLook3f().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;*/ - // Clamp and re-scale - if (sgRatio > M3D_PIDIV2) - sgRatio = M3D_PIDIV2; - else if (sgRatio < -M3D_PIDIV2) - sgRatio = -M3D_PIDIV2; + // Clamp + if (sgRatio > 1.f) + sgRatio = 1.f; + else if (sgRatio < 0.f) + sgRatio = 0.f; - return ((sgRatio - M3D_PIDIV2) / M3D_PI) + 1.f; + return sgRatio; } inline static bool VertexClipTest(M3D_F4& V, sf::Vector2f& RTsize, float gb_factor) {