Skip to content

Commit 6db0009

Browse files
committed
FixZBufferPrecision: greatly reduces z-fighting/distant object pop-in
1 parent 93459e6 commit 6db0009

File tree

7 files changed

+76
-14
lines changed

7 files changed

+76
-14
lines changed

Outrun2006Tweaks.ini

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,25 @@
22
# Framelimit: The max framerate for the game to use.
33
# This will also override the fullscreen refresh rate that the game requests.
44
# Set to 0 to disable this framelimiter, in case you want to use an external one instead.
5+
# (if game doesn't run at full framerate-limit setting, try checking with "DX/WINDOWED = 1" in outrun2006.ini)
56
FramerateLimit = 60
67

7-
# FramerateLimitMode: Improve accuracy of the framerate limiter at a cost of higher CPU usage.
8+
# FramerateLimitMode: Improves accuracy of the framerate limiter at a cost of higher CPU usage.
9+
# The default 0 should work fine for most people, but if you have issues it might be worth trying the accurate mode.
810
# 0 = efficient mode
911
# 1 = accurate mode
1012
FramerateLimitMode = 0
1113

1214
# FramerateFastLoad: Unlimits framerate during load screens to help reduce load times.
1315
# 0 = disable
14-
# 1 = unlimit framerate
15-
# 2 = unlimit framerate & disable vsync (fastest but may cause screen flash)
16+
# 1 = unlimit framerate during load screens
17+
# 2 = unlimit framerate & disable vsync during load screens (fastest load times but may cause screen flash)
1618
FramerateFastLoad = 1
1719

18-
# FramerateUnlockExperimental: Prevents game from speeding up when playing with FramerateLimit above 60FPS.
20+
# FramerateUnlockExperimental: Fixes game speeding up when playing with FramerateLimit above 60FPS.
1921
# Works by forcing game to only update at 60Hz, while rendering is allowed to run at a higher rate.
20-
# Though since game still runs at 60Hz internally this isn't as good as a true framerate unlock, but might still be useful for some.
21-
# (certain textures/UI elements may animate faster at higher FPS, but gameplay should remain the same speed)
22+
# Since game still runs at 60Hz internally this isn't as good as a true framerate unlock, but might still be useful for some.
23+
# (some textures/UI elements may animate faster at higher FPS, but gameplay should remain the same speed)
2224
# Should be fine to leave this enabled in most cases, but if you have issues feel free to disable this here.
2325
FramerateUnlockExperimental = true
2426

@@ -53,11 +55,14 @@ AnisotropicFiltering = 16
5355
# For best results use this with "DX/ANTIALIASING = 2" inside outrun2006.ini
5456
TransparencySupersampling = true
5557

56-
# ScreenEdgeCullFix: Fixes issues with certain stage objects being culled out before they reach edge of screen when playing at non-4:3 aspect ratio.
58+
# ScreenEdgeCullFix: Fixes certain stage objects being culled out before they reach edge of screen, when playing at non-4:3 aspect ratio.
5759
ScreenEdgeCullFix = true
5860

5961
# DisableVehicleLODs: Disables LODs on vehicles, reducing the ugly pop-in they have.
6062
DisableVehicleLODs = true
6163

6264
# DisableStageCulling: Disables culling of certain stage objects, so most distant objects won't obviously pop in to view.
6365
DisableStageCulling = true
66+
67+
# FixZBufferPrecision: Fixes Z-Buffer precision issues, heavily reducing z-fighting and distant object drawing issues (eg. signs/buildings will have much less pop-in)
68+
FixZBufferPrecision = true

README.md

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ A wrapper DLL that can patch in some minor fixes & tweaks into Outrun 2006: Coas
33

44
### Features
55
- Game can now run in borderless windowed mode; mouse cursor will now be hidden while game is active
6-
- Adds a built-in framelimiter to prevent game from speeding up (along with an optional fix to allow higher FPS without speedup)
6+
- Adds a built-in framelimiter to prevent game from speeding up (along with an optional fix that can allow higher FPS without speedup)
77
- Fixes objects being culled out before reaching edge of screen
88
- Allows disabling vehicle LODs to reduce the ugly pop-in of them
99
- Disables culling of certain stage objects
10-
- Can force anisotropic filtering level & enable transparency supersampling, greatly reducing aliasing around the edges of track. (set `DX/ANTIALIASING = 2` in outrun2006.ini for best results)
10+
- Fixes Z-buffer precision issues, greatly reducing z-fighting & distant object pop-in
11+
- Can force anisotropic filtering level & enable transparency supersampling, greatly reducing aliasing around the edges of the track. (set `DX/ANTIALIASING = 2` in outrun2006.ini for best results)
1112
- Automatically disables DPI scaling on the game window, fixing scaling issues with certain setups
12-
- Allows game to load in lens flare data from correct path when needed, fixing lens flare issues.
13+
- Fixes broken lens flare effect by making game load it from correct path
14+
- Heavily reduced load times by disabling framelimiter/vsync during load screens
1315

1416
All the above can be toggled/customized via the Outrun2006Tweaks.ini file.
1517

@@ -18,9 +20,9 @@ Since the game will still internally update at 60FPS this won't give as much ben
1820
(some things like animated textures & UI text also unfortunately have speed issues with it...)
1921

2022
### Setup
21-
Since the Steam/DVD releases are packed with ancient DRM that doesn't play well with DLL wrappers, a replacement game EXE is included with this tweaks pack.
23+
Since Steam/DVD releases are packed with ancient DRM that doesn't play well with DLL wrappers, this pack includes a replacement game EXE to run the game with.
2224

23-
This EXE should be compatible with both the Steam release and the original DVD version.
25+
This EXE should be compatible with both the Steam release & the original DVD version, along with most OR2006 mods.
2426

2527
To set it up just extract the files from the release ZIP into your `Outrun2006 Coast 2 Coast` folder, where `OR2006C2C.EXE` is located, replacing the original EXE.
2628

src/dllmain.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ namespace Settings
101101
ScreenEdgeCullFix = ini.Get("Graphics", "ScreenEdgeCullFix", std::move(ScreenEdgeCullFix));
102102
DisableVehicleLODs = ini.Get("Graphics", "DisableVehicleLODs", std::move(DisableVehicleLODs));
103103
DisableStageCulling = ini.Get("Graphics", "DisableStageCulling", std::move(DisableStageCulling));
104+
FixZBufferPrecision = ini.Get("Graphics", "FixZBufferPrecision", std::move(FixZBufferPrecision));
104105

105106
return true;
106107
}

src/game.hpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,15 @@ typedef struct tagSphere
5252
float f2;
5353
float f3;
5454
} Sphere;
55+
56+
typedef struct tgaEvWorkCamera // [sic]
57+
{
58+
uint8_t unk_0[0xBC];
59+
float perspective_znear_BC;
60+
float perspective_zfar_C0;
61+
uint8_t unk_C4[0xC];
62+
uint8_t unk_D0[0x34A - 0xD0];
63+
char camera_mode_34A;
64+
uint8_t unk_34B[0x5];
65+
uint8_t unk_350[0x64];
66+
} EvWorkCamera;

src/hooks_graphics.cpp

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,47 @@ class DisableVehicleLODs : public Hook
160160
};
161161
DisableVehicleLODs DisableVehicleLODs::instance;
162162

163+
class FixZBufferPrecision : public Hook
164+
{
165+
const static int CalcCameraMatrix_Addr = 0x84BD0;
166+
167+
inline static SafetyHookInline hook_orig = {};
168+
169+
static void destination(EvWorkCamera* camera)
170+
{
171+
// 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
173+
174+
if (camera->camera_mode_34A == 2) // only set znear to 1 if we're in the third-person cam mode
175+
camera->perspective_znear_BC = 1.0f;
176+
else
177+
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
178+
179+
hook_orig.call(camera);
180+
}
181+
182+
public:
183+
std::string_view description() override
184+
{
185+
return "FixZBufferPrecision";
186+
}
187+
188+
bool validate() override
189+
{
190+
return Settings::FixZBufferPrecision;
191+
}
192+
193+
bool apply() override
194+
{
195+
hook_orig = safetyhook::create_inline(Module::exe_ptr(CalcCameraMatrix_Addr), destination);
196+
197+
return !!hook_orig;
198+
}
199+
200+
static FixZBufferPrecision instance;
201+
};
202+
FixZBufferPrecision FixZBufferPrecision::instance;
203+
163204
class TransparencySupersampling : public Hook
164205
{
165206
const static int DeviceInitHookAddr = 0xEC2F;

src/plugin.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ namespace Settings
5151
inline bool ScreenEdgeCullFix = true;
5252
inline bool DisableVehicleLODs = true;
5353
inline bool DisableStageCulling = true;
54+
inline bool FixZBufferPrecision = true;
5455
}
5556

5657
namespace Util

src/resource.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
#endif
1515

1616
#define MODULE_VERSION_MAJOR 0
17-
#define MODULE_VERSION_MINOR 1
18-
#define MODULE_VERSION_BUILD 1
17+
#define MODULE_VERSION_MINOR 2
18+
#define MODULE_VERSION_BUILD 0
1919
#define MODULE_VERSION_REVISION 0
2020

2121
#define STR(value) #value

0 commit comments

Comments
 (0)