# Rendering Optimizations in Lighthouse: How HarbourMasters Optimizes Banjo-Kazooie for Modern GPUs

> Discover Lighthouse rendering optimizations like draw-distance scaling and frustum culling. See how HarbourMasters optimizes Banjo-Kazooie for modern GPUs by reducing overdraw and CPU overhead.

- Repository: [Harbour Masters/Lighthouse](https://github.com/HarbourMasters/Lighthouse)
- Tags: performance
- Published: 2026-08-04

---

**Lighthouse employs eight distinct rendering optimizations—including adjustable draw-distance scaling, padded frustum culling, and stable insertion sorting—to eliminate overdraw and reduce CPU overhead when running the 1998 Nintendo 64 classic on contemporary graphics hardware.**

The HarbourMasters/Lighthouse project is a reverse-engineered PC port of *Banjo-Kazooie* that transforms the original fixed-function console renderer into a scalable modern engine. These rendering optimizations for modern GPUs allow the game to leverage increased fill-rate, memory bandwidth, and compute power while preserving the authentic visual experience.

## Adjustable Draw-Distance and Level-of-Detail Control

Lighthouse exposes **per-user control over visibility distance** through the `port_drawDistanceMul` multiplier. This cvar scales both the cull distance and LOD thresholds, letting the engine render farther objects only when users request higher settings.

In [`src/port/Patches/GraphicsPatches.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/port/Patches/GraphicsPatches.cpp), the engine checks this multiplier before submitting geometry to the GPU. Disabling LOD entirely via `Graphics.DisableLOD` removes the mip-map and geometry-simplification step, useful for GPUs with ample memory that can handle full-detail models at any distance.

```cpp
// Increase draw distance (max = 6)
CVarSetInteger(CVAR_DRAW_DISTANCE, 4);   // 4× normal distance

// Turn off Level-of-Detail (LOD) culling
CVarSetInteger(CVAR_DISABLE_LOD, 1);

```

## Enhanced Occlusion Culling for Level Geometry

The **GEOCULL_CONSUMER_ENHANCEMENT** system in [`GraphicsPatches.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/GraphicsPatches.cpp) extends the original portal-culling with custom rules for specific geometry. When draw-distance is maximized, this forces certain portal-cull geometry—such as the stonehenge structure in Mumbo's Mountain—to remain visible, preventing hidden geometry from being unnecessarily processed.

This enhancement addresses edge cases where aggressive culling would break visual continuity in expanded view distances.

## Padded Frustum Culling with Cached Plane Computation

The [`src/port/Patches/PerfPatches.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/port/Patches/PerfPatches.cpp) file implements **padded frustum culling** to reduce per-object cull checks. The key technique:

- Frustum planes are widened by `kDrawDistCullPadDeg` (configurable padding in degrees)
- Plane equations are recomputed **only when the camera moves**
- Far-away objects stay visible without triggering expensive per-object checks

This cuts draw call submission overhead significantly on CPU-bound systems.

## Stable Insertion Sort for Cube Prop Rendering

Lighthouse replaces the original `$__cube_sort` routine with a **stable insertion sort** that executes in a single pass on already-sorted data. As implemented in [`PerfPatches.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/PerfPatches.cpp), this optimization dramatically reduces sorting overhead each frame—critical for scenes with many interactive props.

The stability guarantee preserves correct draw-order for transparent and overlapping objects.

## Optimized Per-Vertex Lighting Calculations

The **light re-color optimization** in [`PerfPatches.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/PerfPatches.cpp) avoids costly square-root operations through early-out logic:

```cpp
// Pseudocode of the optimization pattern:
if (light_outside_fade_range) {
    // Skip sqrtf entirely
    distance_sq = raw_distance_squared;
} else {
    // Only compute sqrt when actually needed
    attenuation = sqrtf(distance_sq);
}

```

This reduces per-vertex lighting cost, particularly in scenes with many dynamic lights.

## Snow Particle Rotation Caching

Particle-heavy scenes like Freezeezy Peak benefit from **trigonometric caching**. The `sHaveTrig` flag in [`PerfPatches.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/PerfPatches.cpp) caches sine and cosine values for camera rotation, reusing them across all snowflakes rather than computing four trig calls per particle per frame.

## Mirror Pass Culling Corrections

Horizontal mirror effects in the original game required special handling. In [`src/port/Patches/MirrorPatches.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/port/Patches/MirrorPatches.cpp), Lighthouse applies mirroring via **projection matrix scaling** and inverts the interpreter's cross-product sign to maintain correct culling. This prevents spurious discard of mirrored geometry that would otherwise disappear due to winding-order changes.

## TLUT State Isolation for Rom-Hack Compatibility

Rom-hack models can leak **texture lookup table (TLUT)** state between draws. The `port_modelRenderResetTLUT` function in [`GraphicsPatches.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/GraphicsPatches.cpp) restores the default palette before each model draw, preventing unnecessary texture state changes that would force GPU pipeline stalls.

## Enabling and Tuning Optimizations

All rendering optimizations expose console variables (cvars) reachable from **Settings → Developer** or via [`lighthouse.cfg.json`](https://github.com/HarbourMasters/Lighthouse/blob/main/lighthouse.cfg.json). Changes register through `RegisterShipInitFunc` objects and take effect after restart.

Example configuration:

```cpp
// Maximum draw distance with padded frustum
CVarSetInteger(CVAR_DRAW_DISTANCE, 6);

// Rare: disable stale-tile fix for Freezeezy Peak lobby door
CVarSetInteger(CVAR_FP_LOBBY_DOOR_TILE, 0);

```

For profiling culling decisions, the debug UI in [`src/port/DevTools/OcclusionDebug.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/port/DevTools/OcclusionDebug.cpp) visualizes bounding volumes and cull results.

## Summary

- **Draw-distance scaling** (`port_drawDistanceMul`) and **LOD control** adapt workload to user preference and GPU capability
- **Padded frustum culling** with camera-movement-triggered recomputation eliminates redundant per-object checks
- **Stable insertion sort** replaces quadratic prop sorting with linear-time behavior on sorted data
- **Lighting and particle optimizations** remove expensive square-root and trigonometric operations from hot paths
- **Mirror culling fixes** and **TLUT reset** maintain correctness for special rendering modes and modded content

These techniques in [`GraphicsPatches.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/GraphicsPatches.cpp), [`PerfPatches.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/PerfPatches.cpp), and [`MirrorPatches.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/MirrorPatches.cpp) collectively allow Lighthouse to scale from modest integrated graphics to high-end discrete GPUs while maintaining the original game's aesthetic.

## Frequently Asked Questions

### How do I maximize draw distance in Lighthouse?

Set `CVAR_DRAW_DISTANCE` to 6 via the console or configuration file. This enables the maximum 6× multiplier and activates padded frustum planes. According to the HarbourMasters/Lighthouse source code, values above 6 are clamped to prevent excessive overdraw.

### Will disabling LOD improve or hurt performance?

**It depends on your GPU.** Disabling LOD via `CVAR_DISABLE_LOD` removes geometry simplification and mip-map selection, increasing vertex and texture bandwidth. Modern GPUs with abundant VRAM and compute headroom often show improved visual clarity with minimal frame-time impact; older or integrated graphics may stall on the additional workload.

### What causes the Freezeezy Peak lobby door to flicker, and how do I fix it?

The original game contains a stale-tile bug in this area. Lighthouse applies a fix by default, but in rare cases this conflicts with certain rom-hacks. Set `CVAR_FP_LOBBY_DOOR_TILE` to 0 in [`lighthouse.cfg.json`](https://github.com/HarbourMasters/Lighthouse/blob/main/lighthouse.cfg.json) to disable the patch, as documented in [`GraphicsPatches.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/GraphicsPatches.cpp).

### Where can I verify that culling optimizations are working correctly?

Use the occlusion debug interface in [`src/port/DevTools/OcclusionDebug.cpp`](https://github.com/HarbourMasters/Lighthouse/blob/main/src/port/DevTools/OcclusionDebug.cpp). This renders bounding volumes and color-codes culled versus visible geometry, letting you confirm that padded frustum planes and portal extensions behave as expected with your specific camera angles and draw-distance settings.