Terrain-sky smooth ratio rendering
This commit is contained in:
parent
bf7b10850e
commit
2854da4053
@ -75,6 +75,7 @@ target_sources(${PROJECT_NAME} PRIVATE
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Engine/Utils/3DMaths_vec.inl"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Engine/Utils/3DMaths_mat.inl"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Engine/Utils/3DMaths_bs.inl"
|
||||
"${CMAKE_CURRENT_SOURCE_DIR}/Engine/Utils/3DMaths_sc.inl"
|
||||
)
|
||||
|
||||
# targets build options
|
||||
|
@ -109,7 +109,6 @@ void Graphic3DRenderer::Draw(sf::RenderTexture& context) {
|
||||
M3D_BoundingFrustum camFrustrum(projMat, false);
|
||||
camFrustrum.Transform(camFrustrum, invViewMat);
|
||||
|
||||
const float sgRatio = std::tan(mMainCamera->GetLook3f().y);
|
||||
// -= Draw the sky =-
|
||||
// To avoid unfilled pixels on screen, the "sky-plane" will be rendered
|
||||
// all over the screen.
|
||||
@ -124,8 +123,15 @@ void Graphic3DRenderer::Draw(sf::RenderTexture& context) {
|
||||
// Depending of the camera pitch, the ratio sky/ground on screen vary.
|
||||
// Like the sky, the ground have an infinite z-depth (any objects will
|
||||
// be rendered over).
|
||||
sf::RectangleShape gndRect(sf::Vector2f(1280, mRTSize.y * (0.5f - sgRatio)));
|
||||
gndRect.setPosition(sf::Vector2f(0, mRTSize.y * (0.5f + sgRatio)));
|
||||
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));
|
||||
} else {
|
||||
gndRect.setSize(sf::Vector2f(1280, mRTSize.y * sgRatio));
|
||||
gndRect.setPosition(sf::Vector2f(0, 0));
|
||||
}
|
||||
gndRect.setFillColor(sf::Color::Green);
|
||||
context.draw(gndRect, sRS);
|
||||
|
||||
@ -228,6 +234,21 @@ void Graphic3DRenderer::UpdateInternalTestObjects() {
|
||||
mRenderList[3]->SetRotation(0.f, thetaAngle, 0.f);
|
||||
}
|
||||
|
||||
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));
|
||||
// Get the camera pitch angle over camera FoV ratio
|
||||
float sgRatio = M3D_ScalarASinEst(mMainCamera->GetLook3f().y) / fovYAngle;
|
||||
|
||||
// Clamp and re-scale
|
||||
if (sgRatio > M3D_PIDIV2)
|
||||
sgRatio = M3D_PIDIV2;
|
||||
else if (sgRatio < -M3D_PIDIV2)
|
||||
sgRatio = -M3D_PIDIV2;
|
||||
|
||||
return ((sgRatio - M3D_PIDIV2) / M3D_PI) + 1.f;
|
||||
}
|
||||
|
||||
inline static bool VertexClipTest(M3D_F4& V, sf::Vector2f& RTsize, float gb_factor) {
|
||||
// Guard band are usually 2-3x the viewport size for the clipping test
|
||||
return (V.x > -RTsize.x*gb_factor*V.w && V.x < RTsize.y*gb_factor*V.w &&
|
||||
|
@ -39,5 +39,6 @@ private:
|
||||
std::vector<std::shared_ptr<WorldObject>> mRenderList; // List of elements to be rendered next frame
|
||||
|
||||
void UpdateInternalTestObjects();
|
||||
float ComputeSGRatio();
|
||||
|
||||
};
|
@ -7,6 +7,7 @@ Camera::Camera() {
|
||||
|
||||
void Camera::SetFrustrum(float fov, float r, float zn, float zf) {
|
||||
//if (!frameDirty)
|
||||
this->fov = fov;
|
||||
M3D_MATRIX pMat = M3D_TransformMatrixFrustrumFovLH(M3D_Deg2Rad(fov), r, zn, zf);
|
||||
M3D_V4StoreF4x4(&mProjMat, pMat);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ public:
|
||||
Camera(Camera const&) = delete;
|
||||
Camera& operator= (Camera const&) = delete;
|
||||
|
||||
float GetFoV() const { return fov; }
|
||||
M3D_VECTOR GetPos() const { return M3D_V4LoadF3(&mPos); }
|
||||
M3D_F3 GetPos3f() const { return mPos; }
|
||||
M3D_VECTOR GetLook() const { return M3D_V4LoadF3(&mLook); }
|
||||
@ -38,9 +39,17 @@ public:
|
||||
void Yaw(float angle);
|
||||
|
||||
private:
|
||||
float fov;
|
||||
|
||||
M3D_F4X4 mProjMat = M3D_MIdentity4x4();
|
||||
M3D_F4X4 mViewMat = M3D_MIdentity4x4();
|
||||
|
||||
/*
|
||||
right-x up-x look-x pos-x
|
||||
right-y up-y look-y pos-y
|
||||
right-z up-z look-z pos-z
|
||||
0 0 0 1
|
||||
*/
|
||||
M3D_F3 mPos = {0.0f, 0.0f, 0.0f};
|
||||
M3D_F3 mRight = {1.0f, 0.0f, 0.0f};
|
||||
M3D_F3 mUp = {0.0f, 1.0f, 0.0f};
|
||||
|
@ -594,6 +594,18 @@ M3D_MATRIX M3D_TransformMatrixRotationAxis(M3D_VECTOR axis, float angle) noexcep
|
||||
M3D_MATRIX M3D_TransformMatrixViewport(float _w, float _h, float _wOffset, float _hOffset) noexcept;
|
||||
|
||||
|
||||
//
|
||||
// Math enhanced trigo
|
||||
//
|
||||
float M3D_ScalarSin(float Value) noexcept;
|
||||
float M3D_ScalarSinEst(float Value) noexcept;
|
||||
float M3D_ScalarCos(float Value) noexcept;
|
||||
float M3D_ScalarCosEst(float Value) noexcept;
|
||||
float M3D_ScalarASin(float Value) noexcept;
|
||||
float M3D_ScalarASinEst(float Value) noexcept;
|
||||
float M3D_ScalarACos(float Value) noexcept;
|
||||
float M3D_ScalarACosEst(float Value) noexcept;
|
||||
|
||||
//
|
||||
// Common values for vector/matrix manipulation
|
||||
//
|
||||
@ -899,3 +911,4 @@ M3D_GCONST M3D_V4F32 M3D_BBoxOffset[8] = {
|
||||
#include "3DMaths_vec.inl"
|
||||
#include "3DMaths_mat.inl"
|
||||
#include "3DMaths_bs.inl"
|
||||
#include "3DMaths_sc.inl"
|
166
Engine/Utils/3DMaths_sc.inl
Normal file
166
Engine/Utils/3DMaths_sc.inl
Normal file
@ -0,0 +1,166 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
inline float M3D_ScalarSin(float Value) noexcept {
|
||||
// Map Value to y in [-pi,pi], x = 2*pi*quotient + remainder.
|
||||
float quotient = M3D_1DIV2PI * Value;
|
||||
if (Value >= 0.0f)
|
||||
quotient = static_cast<float>(static_cast<int>(quotient + 0.5f));
|
||||
else
|
||||
quotient = static_cast<float>(static_cast<int>(quotient - 0.5f));
|
||||
float y = Value - M3D_2PI * quotient;
|
||||
|
||||
// Map y to [-pi/2,pi/2] with sin(y) = sin(Value).
|
||||
if (y > M3D_PIDIV2)
|
||||
y = M3D_PI - y;
|
||||
else if (y < -M3D_PIDIV2)
|
||||
y = -M3D_PI - y;
|
||||
|
||||
// 11-degree minimax approximation
|
||||
float y2 = y * y;
|
||||
return (((((-2.3889859e-08f * y2 + 2.7525562e-06f) * y2 - 0.00019840874f) * y2 + 0.0083333310f) * y2 - 0.16666667f) * y2 + 1.0f) * y;
|
||||
}
|
||||
|
||||
inline float M3D_ScalarSinEst(float Value) noexcept {
|
||||
// Map Value to y in [-pi,pi], x = 2*pi*quotient + remainder.
|
||||
float quotient = M3D_1DIV2PI * Value;
|
||||
if (Value >= 0.0f)
|
||||
quotient = static_cast<float>(static_cast<int>(quotient + 0.5f));
|
||||
else
|
||||
quotient = static_cast<float>(static_cast<int>(quotient - 0.5f));
|
||||
float y = Value - M3D_2PI * quotient;
|
||||
|
||||
// Map y to [-pi/2,pi/2] with sin(y) = sin(Value).
|
||||
if (y > M3D_PIDIV2)
|
||||
y = M3D_PI - y;
|
||||
else if (y < -M3D_PIDIV2)
|
||||
y = -M3D_PI - y;
|
||||
|
||||
// 7-degree minimax approximation
|
||||
float y2 = y * y;
|
||||
return (((-0.00018524670f * y2 + 0.0083139502f) * y2 - 0.16665852f) * y2 + 1.0f) * y;
|
||||
}
|
||||
|
||||
inline float M3D_ScalarCos(float Value) noexcept {
|
||||
// Map Value to y in [-pi,pi], x = 2*pi*quotient + remainder.
|
||||
float quotient = M3D_1DIV2PI * Value;
|
||||
if (Value >= 0.0f)
|
||||
quotient = static_cast<float>(static_cast<int>(quotient + 0.5f));
|
||||
else
|
||||
quotient = static_cast<float>(static_cast<int>(quotient - 0.5f));
|
||||
float y = Value - M3D_2PI * quotient;
|
||||
|
||||
// Map y to [-pi/2,pi/2] with cos(y) = sign*cos(x).
|
||||
float sign;
|
||||
if (y > M3D_PIDIV2) {
|
||||
y = M3D_PI - y;
|
||||
sign = -1.0f;
|
||||
} else if (y < -M3D_PIDIV2) {
|
||||
y = -M3D_PI - y;
|
||||
sign = -1.0f;
|
||||
} else {
|
||||
sign = +1.0f;
|
||||
}
|
||||
|
||||
// 10-degree minimax approximation
|
||||
float y2 = y * y;
|
||||
float p = ((((-2.6051615e-07f * y2 + 2.4760495e-05f) * y2 - 0.0013888378f) * y2 + 0.041666638f) * y2 - 0.5f) * y2 + 1.0f;
|
||||
return sign * p;
|
||||
}
|
||||
|
||||
inline float M3D_ScalarCosEst(float Value) noexcept {
|
||||
// Map Value to y in [-pi,pi], x = 2*pi*quotient + remainder.
|
||||
float quotient = M3D_1DIV2PI * Value;
|
||||
if (Value >= 0.0f)
|
||||
quotient = static_cast<float>(static_cast<int>(quotient + 0.5f));
|
||||
else
|
||||
quotient = static_cast<float>(static_cast<int>(quotient - 0.5f));
|
||||
float y = Value - M3D_2PI * quotient;
|
||||
|
||||
// Map y to [-pi/2,pi/2] with cos(y) = sign*cos(x).
|
||||
float sign;
|
||||
if (y > M3D_PIDIV2) {
|
||||
y = M3D_PI - y;
|
||||
sign = -1.0f;
|
||||
} else if (y < -M3D_PIDIV2) {
|
||||
y = -M3D_PI - y;
|
||||
sign = -1.0f;
|
||||
} else {
|
||||
sign = +1.0f;
|
||||
}
|
||||
|
||||
// 6-degree minimax approximation
|
||||
float y2 = y * y;
|
||||
float p = ((-0.0012712436f * y2 + 0.041493919f) * y2 - 0.49992746f) * y2 + 1.0f;
|
||||
return sign * p;
|
||||
}
|
||||
|
||||
inline float M3D_ScalarASin(float Value) noexcept {
|
||||
// Clamp input to [-1,1].
|
||||
bool nonnegative = (Value >= 0.0f);
|
||||
float x = std::fabs(Value);
|
||||
float omx = 1.0f - x;
|
||||
if (omx < 0.0f)
|
||||
omx = 0.0f;
|
||||
float root = std::sqrt(omx);
|
||||
|
||||
// 7-degree minimax approximation
|
||||
float result = ((((((-0.0012624911f * x + 0.0066700901f) * x - 0.0170881256f) * x + 0.0308918810f) * x - 0.0501743046f) * x + 0.0889789874f) * x - 0.2145988016f) * x + 1.5707963050f;
|
||||
result *= root; // acos(|x|)
|
||||
|
||||
// acos(x) = pi - acos(-x) when x < 0, asin(x) = pi/2 - acos(x)
|
||||
return (nonnegative ? M3D_PIDIV2 - result : result - M3D_PIDIV2);
|
||||
}
|
||||
|
||||
inline float M3D_ScalarASinEst(float Value) noexcept {
|
||||
// Clamp input to [-1,1].
|
||||
bool nonnegative = (Value >= 0.0f);
|
||||
float x = std::fabs(Value);
|
||||
float omx = 1.0f - x;
|
||||
if (omx < 0.0f)
|
||||
{
|
||||
omx = 0.0f;
|
||||
}
|
||||
float root = std::sqrt(omx);
|
||||
|
||||
// 3-degree minimax approximation
|
||||
float result = ((-0.0187293f * x + 0.0742610f) * x - 0.2121144f) * x + 1.5707288f;
|
||||
result *= root; // acos(|x|)
|
||||
|
||||
// acos(x) = pi - acos(-x) when x < 0, asin(x) = pi/2 - acos(x)
|
||||
return (nonnegative ? M3D_PIDIV2 - result : result - M3D_PIDIV2);
|
||||
}
|
||||
|
||||
inline float M3D_ScalarACos(float Value) noexcept {
|
||||
// Clamp input to [-1,1].
|
||||
bool nonnegative = (Value >= 0.0f);
|
||||
float x = std::fabs(Value);
|
||||
float omx = 1.0f - x;
|
||||
if (omx < 0.0f)
|
||||
omx = 0.0f;
|
||||
float root = std::sqrt(omx);
|
||||
|
||||
// 7-degree minimax approximation
|
||||
float result = ((((((-0.0012624911f * x + 0.0066700901f) * x - 0.0170881256f) * x + 0.0308918810f) * x - 0.0501743046f) * x + 0.0889789874f) * x - 0.2145988016f) * x + 1.5707963050f;
|
||||
result *= root;
|
||||
|
||||
// acos(x) = pi - acos(-x) when x < 0
|
||||
return (nonnegative ? result : M3D_PI - result);
|
||||
}
|
||||
|
||||
inline float M3D_ScalarACosEst(float Value) noexcept {
|
||||
// Clamp input to [-1,1].
|
||||
bool nonnegative = (Value >= 0.0f);
|
||||
float x = std::fabs(Value);
|
||||
float omx = 1.0f - x;
|
||||
if (omx < 0.0f)
|
||||
omx = 0.0f;
|
||||
float root = std::sqrt(omx);
|
||||
|
||||
// 3-degree minimax approximation
|
||||
float result = ((-0.0187293f * x + 0.0742610f) * x - 0.2121144f) * x + 1.5707288f;
|
||||
result *= root;
|
||||
|
||||
// acos(x) = pi - acos(-x) when x < 0
|
||||
return (nonnegative ? result : M3D_PI - result);
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user