retro 3d psx prototype

building a retro 3d psx prototype in godot 4

This prototype started as a tight experiment in combining 90s-era rendering with modern, physics-driven interactions. Built in Godot 4.6, it mixes retro visual quirks with systems like non‑euclidean portals, physics-based object interaction, and an AI that responds to being photographed.

project overview

Rather than just slapping a low-res filter on a modern scene, the goal was to recreate the behaviors of PS1 hardware—vertex jitter, affine texture warping, and low-resolution viewport scaling—so the visuals feel authentic, not pasted on. Underneath that is a playable template with portals, object dragging powered by JoltPhysics3D, and a creepy enemy that freezes when you look at it.

psx shader pipeline

The shader does three main things to sell the retro look:

Example snippet:

float i = (1.0 - jitter) * min(VIEWPORT_SIZE.x, VIEWPORT_SIZE.y) / 2.0;
float w = (PROJECTION_MATRIX * vec4(VERTEX, 1.0)).w;
VERTEX = round(VERTEX / w * i) / i * w;

non-euclidean portals

Portals use subviewports so each opening renders the scene from the linked portal’s perspective. The linked camera’s transform is updated every frame relative to the player, keeping the view consistent while walking through.

Key idea:

var rel = global_transform.affine_inverse() * player.camera.global_transform
linked_portal.cam.global_transform = linked_portal.global_transform * rel

Portals also trigger a short post-process effect—chromatic aberration and vignette—to make the transition feel weighty.

photographic ai (enemy behaviour, mannequins)

The mannequins follow a simple rule: they stay still while visible and move when you aren’t looking. The camera/photo mechanic ties into this—if you take and keep a photo of a mannequin, it stays frozen until you remove or review that photo.

If destroyed, mannequins break into rigid fragments and the physics engine handles the resulting debris.

graph TD
    A[Mannequin State] --> B{Is Player Looking?}
    B -->|Yes| C[Freeze Movement]
    B -->|No| D{Has Active Photo?}
    D -->|Yes| C
    D -->|No| E[Move Towards Player]
    E --> F{Destroyed?}
    F -->|Yes| G[Fracture into Rigid Fragments & Physics Debris]
            

gameplay systems

tech stack

why this approach

Putting retro limitations at the core of the design creates tension and helps the game feel distinct. The shaders make environments feel unstable and uncanny, which works well with portals and physics-driven enemy interactions. It’s a small, focused template that’s easy to extend into a tense, atmospheric game.

This retro 3D PSX prototype demonstrates how combining authentic classic hardware limitations with modern physics engine interactions can create a highly atmospheric and tense gameplay loop.