From 98c8d459e4bee9add644c69a1c9a15dc615e8c70 Mon Sep 17 00:00:00 2001 From: UnknownShadow200 Date: Sat, 5 Dec 2020 23:48:25 +1100 Subject: [PATCH] D3D9: Don't reduce zNear at default 70 FOV, reduces z-fighting with far away stuff --- src/Camera.c | 2 +- src/Graphics.c | 30 +++++++++++++++++------------- src/Graphics.h | 4 ++-- src/HeldBlockRenderer.c | 3 +-- src/Vectors.c | 13 +++++-------- src/Vectors.h | 1 - 6 files changed, 26 insertions(+), 27 deletions(-) diff --git a/src/Camera.c b/src/Camera.c index 8381b598d..f67923393 100644 --- a/src/Camera.c +++ b/src/Camera.c @@ -27,7 +27,7 @@ static void Camera_OnRawMovement(float deltaX, float deltaY) { static void PerspectiveCamera_GetProjection(struct Matrix* proj) { float fovy = Game_Fov * MATH_DEG2RAD; float aspectRatio = (float)Game.Width / (float)Game.Height; - Gfx_CalcPerspectiveMatrix(fovy, aspectRatio, Gfx.MinZNear, (float)Game_ViewDistance, proj); + Gfx_CalcPerspectiveMatrix(fovy, aspectRatio, (float)Game_ViewDistance, proj); } static void PerspectiveCamera_GetView(struct Matrix* mat) { diff --git a/src/Graphics.c b/src/Graphics.c index cc96ce7ab..f352bbc46 100644 --- a/src/Graphics.c +++ b/src/Graphics.c @@ -29,6 +29,8 @@ static const int strideSizes[2] = { SIZEOF_VERTEX_COLOURED, SIZEOF_VERTEX_TEXTUR static int curStride, curFormat = -1; /* Whether mipmaps must be created for all dimensions down to 1x1 or not */ static cc_bool customMipmapsLevels; +#define ORTHO_NEAR -10000.0f +#define ORTHO_FAR 10000.0f static cc_bool gfx_vsync, gfx_fogEnabled; static float gfx_minFrameMs; @@ -312,6 +314,7 @@ static IDirect3D9* d3d; static IDirect3DDevice9* device; static DWORD createFlags = D3DCREATE_HARDWARE_VERTEXPROCESSING; static D3DFORMAT viewFormat, depthFormat; +static int depthBits; static float totalMem; static void D3D9_RestoreRenderStates(void); @@ -438,8 +441,7 @@ void Gfx_Create(void) { CreateD3D9(); FindCompatibleViewFormat(); FindCompatibleDepthFormat(); - /* With reversed z depth, near Z plane can be much closer with sufficient depth buffer precision */ - Gfx.MinZNear = D3D9_DepthBufferBits() < 24 ? 0.05f : 0.001953125f; + depthBits = D3D9_DepthBufferBits(); customMipmapsLevels = true; Gfx.ManagedTextures = true; @@ -915,16 +917,19 @@ void Gfx_LoadIdentityMatrix(MatrixType type) { IDirect3DDevice9_SetTransform(device, matrix_modes[type], (const D3DMATRIX*)&Matrix_Identity); } -#define d3d9_zN -10000.0f -#define d3d9_zF 10000.0f void Gfx_CalcOrthoMatrix(float width, float height, struct Matrix* matrix) { - Matrix_Orthographic(matrix, 0.0f, width, 0.0f, height, d3d9_zN, d3d9_zF); - matrix->Row2.Z = 1.0f / (d3d9_zN - d3d9_zF); - matrix->Row3.Z = d3d9_zN / (d3d9_zN - d3d9_zF); + Matrix_Orthographic(matrix, 0.0f, width, 0.0f, height, ORTHO_NEAR, ORTHO_FAR); + matrix->Row2.Z = 1.0f / (ORTHO_NEAR - ORTHO_FAR); + matrix->Row3.Z = ORTHO_NEAR / (ORTHO_NEAR - ORTHO_FAR); } -void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zNear, float zFar, struct Matrix* matrix) { +void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zFar, struct Matrix* matrix) { + /* With reversed z depth, near Z plane can be much closer (with sufficient depth buffer precision) */ + /* This reduces clipping with high FOV without sacrificing depth precision for faraway objects */ + /* However for low FOV, don't reduce near Z in order to gain a bit more depth precision */ + float zNear = (depthBits < 24 || fov <= 70) ? 0.05f : 0.001953125f; Matrix_PerspectiveFieldOfView(matrix, fov, aspect, zNear, zFar); - /* Adjust the projection matrix to produce reversed Z values. */ + + /* Adjust the projection matrix to produce reversed Z values */ matrix->Row2.Z = -matrix->Row2.Z - 1.0f; matrix->Row3.Z = -matrix->Row3.Z; } @@ -1009,7 +1014,6 @@ static const char* D3D9_StrFlags(void) { void Gfx_GetApiInfo(cc_string* info) { D3DADAPTER_IDENTIFIER9 adapter = { 0 }; int pointerSize = sizeof(void*) * 8; - int depthBits = D3D9_DepthBufferBits(); float curMem; IDirect3D9_GetAdapterIdentifier(d3d, D3DADAPTER_DEFAULT, 0, &adapter); @@ -1108,7 +1112,6 @@ static GL_SetupVBRangeFunc gfx_setupVBRangeFunc; static void GL_CheckSupport(void); void Gfx_Create(void) { GLContext_Create(); - Gfx.MinZNear = 0.1f; glGetIntegerv(GL_MAX_TEXTURE_SIZE, &Gfx.MaxTexWidth); Gfx.MaxTexHeight = Gfx.MaxTexWidth; Gfx.Created = true; @@ -1268,9 +1271,10 @@ void Gfx_SetDepthWrite(cc_bool enabled) { glDepthMask(enabled); } void Gfx_SetDepthTest(cc_bool enabled) { gl_Toggle(GL_DEPTH_TEST); } void Gfx_CalcOrthoMatrix(float width, float height, struct Matrix* matrix) { - Matrix_Orthographic(matrix, 0.0f, width, 0.0f, height, -10000.0f, 10000.0f); + Matrix_Orthographic(matrix, 0.0f, width, 0.0f, height, ORTHO_NEAR, ORTHO_FAR); } -void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zNear, float zFar, struct Matrix* matrix) { +void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zFar, struct Matrix* matrix) { + float zNear = 0.1f; Matrix_PerspectiveFieldOfView(matrix, fov, aspect, zNear, zFar); } diff --git a/src/Graphics.h b/src/Graphics.h index a864eb9ef..392ed71b4 100644 --- a/src/Graphics.h +++ b/src/Graphics.h @@ -35,7 +35,7 @@ void Gfx_Free(void); CC_VAR extern struct _GfxData { /* Maximum dimensions textures can be created up to. (usually 1024 to 16384) */ int MaxTexWidth, MaxTexHeight; - float MinZNear; + float _unused; /* Whether context graphics has been lost (all creation/render calls fail) */ cc_bool LostContext; /* Whether some textures are created with mipmaps. */ @@ -177,7 +177,7 @@ CC_API void Gfx_LoadIdentityMatrix(MatrixType type); /* Calculates an orthographic matrix suitable with this backend. (usually for 2D) */ void Gfx_CalcOrthoMatrix(float width, float height, struct Matrix* matrix); /* Calculates a projection matrix suitable with this backend. (usually for 3D) */ -void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zNear, float zFar, struct Matrix* matrix); +void Gfx_CalcPerspectiveMatrix(float fov, float aspect, float zFar, struct Matrix* matrix); /* Outputs a .png screenshot of the backbuffer. */ cc_result Gfx_TakeScreenshot(struct Stream* output); diff --git a/src/HeldBlockRenderer.c b/src/HeldBlockRenderer.c index 0300ed4d0..317ce3f9f 100644 --- a/src/HeldBlockRenderer.c +++ b/src/HeldBlockRenderer.c @@ -95,8 +95,7 @@ static void SetBaseOffset(void) { static void OnProjectionChanged(void* obj) { float fov = 70.0f * MATH_DEG2RAD; float aspectRatio = (float)Game.Width / (float)Game.Height; - float zNear = Gfx.MinZNear; - Gfx_CalcPerspectiveMatrix(fov, aspectRatio, zNear, (float)Game_ViewDistance, &held_blockProjection); + Gfx_CalcPerspectiveMatrix(fov, aspectRatio, (float)Game_ViewDistance, &held_blockProjection); } /* Based off incredible gifs from (Thanks goodlyay!) diff --git a/src/Vectors.c b/src/Vectors.c index a4b31374e..c6159e56f 100644 --- a/src/Vectors.c +++ b/src/Vectors.c @@ -183,20 +183,17 @@ void Matrix_Orthographic(struct Matrix* result, float left, float right, float t static double Tan_Simple(double x) { return Math_Sin(x) / Math_Cos(x); } void Matrix_PerspectiveFieldOfView(struct Matrix* result, float fovy, float aspect, float zNear, float zFar) { float c = zNear * (float)Tan_Simple(0.5f * fovy); - Matrix_PerspectiveOffCenter(result, -c * aspect, c * aspect, -c, c, zNear, zFar); -} -void Matrix_PerspectiveOffCenter(struct Matrix* result, float left, float right, float bottom, float top, float zNear, float zFar) { /* Transposed, source https://msdn.microsoft.com/en-us/library/dd373537(v=vs.85).aspx */ + /* For a FOV based perspective matrix, left/right/top/bottom are calculated as: */ + /* left = -c * aspect, right = c * aspect, bottom = -c, top = c */ + /* Calculations are simplified because of left/right and top/bottom symmetry */ *result = Matrix_Identity; result->Row3.W = 0.0f; - result->Row0.X = (2.0f * zNear) / (right - left); - result->Row1.Y = (2.0f * zNear) / (top - bottom); + result->Row0.X = zNear / (c * aspect); + result->Row1.Y = zNear / c; result->Row3.Z = -(2.0f * zFar * zNear) / (zFar - zNear); - - result->Row2.X = (right + left) / (right - left); - result->Row2.Y = (top + bottom) / (top - bottom); result->Row2.Z = -(zFar + zNear) / (zFar - zNear); result->Row2.W = -1.0f; } diff --git a/src/Vectors.h b/src/Vectors.h index 8f6f50b17..00cb09866 100644 --- a/src/Vectors.h +++ b/src/Vectors.h @@ -123,7 +123,6 @@ CC_API void Matrix_Mul(struct Matrix* result, const struct Matrix* left, const s void Matrix_Orthographic(struct Matrix* result, float left, float right, float top, float bottom, float zNear, float zFar); void Matrix_PerspectiveFieldOfView(struct Matrix* result, float fovy, float aspect, float zNear, float zFar); -void Matrix_PerspectiveOffCenter(struct Matrix* result, float left, float right, float bottom, float top, float zNear, float zFar); void Matrix_LookRot(struct Matrix* result, Vec3 pos, Vec2 rot); cc_bool FrustumCulling_SphereInFrustum(float x, float y, float z, float radius);