Skip to content

Commit 754eda9

Browse files
committed
FixZBufferPrecision: fix lens flare being clipped out
resets znear before screen effects are drawn, kinda hacky but easier than trying to reposition each screen effect (wonder if this could be inverted so it'd only change znear temporarily while stage is drawing, would solve any car clipping issues... no luck with that yet)
1 parent 25683f3 commit 754eda9

File tree

3 files changed

+50
-20
lines changed

3 files changed

+50
-20
lines changed

Outrun2006Tweaks.ini

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,5 +69,4 @@ DisableVehicleLODs = true
6969
DisableStageCulling = true
7070

7171
# FixZBufferPrecision: Fixes Z-Buffer precision issues, greatly reducing z-fighting and distant object drawing issues (eg. signs/buildings will have much less pop-in)
72-
# Note: disabled by default as it may stop lens-flare effect from displaying, up to you which is more important
73-
FixZBufferPrecision = false
72+
FixZBufferPrecision = true

src/hooks_graphics.cpp

Lines changed: 48 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -163,29 +163,57 @@ DisableVehicleLODs DisableVehicleLODs::instance;
163163
class FixZBufferPrecision : public Hook
164164
{
165165
const static int CalcCameraMatrix_Addr = 0x84BD0;
166+
const static int Clr_SceneEffect_Addr = 0xBE70;
166167

167-
inline static SafetyHookInline hook_orig = {};
168+
inline static SafetyHookInline CalcCameraMatrix = {};
168169

169-
static void destination(EvWorkCamera* camera)
170+
static inline bool allow_znear_override = true;
171+
static void CalcCameraMatrix_dest(EvWorkCamera* camera)
170172
{
171173
// improve z-buffer precision by increasing znear
172-
// game default is 0.1, which reduces precision of far objects massively, causing z-fighting and objects not drawing properly
174+
// game default is 0.1 which reduces precision of far objects massively, causing z-fighting and objects not drawing properly
173175

174-
// only set znear to 1 if...
175-
if ((camera->camera_mode_34A == 2 || camera->camera_mode_34A == 0) // ... in third-person or FPV
176-
&& camera->camera_mode_timer_364 == 0 // ... not switching cameras
177-
&& *Game::current_mode == STATE_GAME) // ... we're in main game state (not in STATE_START cutscene etc)
176+
if (allow_znear_override)
178177
{
179-
camera->perspective_znear_BC = 0.99f; // 1.0 seems to cause sun flickering, but seems fine with 0.99
180-
}
181-
else
182-
{
183-
if (camera->camera_mode_timer_364 != 0 || *Game::current_mode != STATE_GAME)
184-
camera->perspective_znear_BC = 0.1f; // set znear to 0.1 during camera switch / cutscene
178+
// only set znear to 1 if...
179+
if ((camera->camera_mode_34A == 2 || camera->camera_mode_34A == 0) // ... in third-person or FPV
180+
&& camera->camera_mode_timer_364 == 0 // ... not switching cameras
181+
&& *Game::current_mode == STATE_GAME) // ... we're in main game state (not in STATE_START cutscene etc)
182+
{
183+
camera->perspective_znear_BC = 1.0f;
184+
}
185185
else
186-
camera->perspective_znear_BC = 0.3f; // 0.3 seems fine for in-car view, doesn't improve as much as 1.0f but still better than 0.1f
186+
{
187+
if (camera->camera_mode_timer_364 != 0 || *Game::current_mode != STATE_GAME)
188+
camera->perspective_znear_BC = 0.1f; // set znear to 0.1 during camera switch / cutscene
189+
else
190+
camera->perspective_znear_BC = 0.3f; // 0.3 seems fine for in-car view, doesn't improve as much as 1.0f but still better than 0.1f
191+
}
187192
}
188-
hook_orig.call(camera);
193+
CalcCameraMatrix.call(camera);
194+
}
195+
196+
// hook Clr_SceneEffect so we can reset camera z-near before screen effects are draw
197+
inline static SafetyHookInline Clr_SceneEffect = {};
198+
static void Clr_SceneEffect_dest(int a1)
199+
{
200+
FixZBufferPrecision::allow_znear_override = false;
201+
202+
EvWorkCamera* camera = Module::exe_ptr<EvWorkCamera>(0x39FE10);
203+
204+
float prev = camera->perspective_znear_BC;
205+
206+
// apply vanilla znear
207+
camera->perspective_znear_BC = 0.05f; // game default = 0.1, but that causes lens flare to slightly clip, 0.05 allows it to fade properly
208+
CalcCameraMatrix_dest(camera);
209+
210+
Clr_SceneEffect.call(a1);
211+
212+
// restore orig znear
213+
camera->perspective_znear_BC = prev;
214+
CalcCameraMatrix_dest(camera);
215+
216+
FixZBufferPrecision::allow_znear_override = true;
189217
}
190218

191219
public:
@@ -201,9 +229,12 @@ class FixZBufferPrecision : public Hook
201229

202230
bool apply() override
203231
{
204-
hook_orig = safetyhook::create_inline(Module::exe_ptr(CalcCameraMatrix_Addr), destination);
232+
CalcCameraMatrix = safetyhook::create_inline(Module::exe_ptr(CalcCameraMatrix_Addr), CalcCameraMatrix_dest);
233+
if (!CalcCameraMatrix)
234+
return false;
205235

206-
return !!hook_orig;
236+
Clr_SceneEffect = safetyhook::create_inline(Module::exe_ptr(Clr_SceneEffect_Addr), Clr_SceneEffect_dest);
237+
return !!Clr_SceneEffect;
207238
}
208239

209240
static FixZBufferPrecision instance;

src/plugin.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ namespace Settings
5252
inline bool ScreenEdgeCullFix = true;
5353
inline bool DisableVehicleLODs = true;
5454
inline bool DisableStageCulling = true;
55-
inline bool FixZBufferPrecision = false;
55+
inline bool FixZBufferPrecision = true;
5656
}
5757

5858
namespace Util

0 commit comments

Comments
 (0)