3D Demo

Interactive 3D scene showcasing the software renderer, ECS, and physics subsystems with keyboard controls.

The 3D demo is the simplest entry point into Aether. It opens a window with a software-rendered scene containing spheres, cubes, a movable player, and a trigger zone -- all driven by the ECS and physics engine without requiring a GPU.

What It Demonstrates

  • Software rasterizer built into aether-renderer, capable of rendering spheres, cubes, shadow blobs, a ground plane, and a HUD overlay at 60 FPS.
  • Entity-Component System (aether-ecs) managing transforms, velocities, rigid bodies, colliders, and network identities for every object in the scene.
  • Physics simulation via aether-physics with gravity, ground clamping, and Rapier3D-backed collision layers.
  • Trigger zones that detect overlapping entities and change color when activated, using TriggerEventQueue.
  • Orbit camera controlled via spherical coordinates with smooth keyboard input.

How to Run

Using the pre-built binary:

aether run 3d-demo

From source (requires Rust stable toolchain):

cargo run -p aether-3d-demo

Controls

KeyAction
W / A / S / DMove the player relative to camera facing
Arrow keysOrbit the camera around the player
QZoom in
EZoom out
RReset physics (respawn objects)
ESCQuit

Movement is relative to the camera angle, so pressing W always moves the player away from the camera regardless of orbit position.

Subsystems Showcased

CrateRole in this demo
aether-ecsWorld storage, entity spawning, component queries, system scheduling
aether-physicsGravity, rigid bodies, colliders, collision layers, trigger detection
aether-rendererSoftware framebuffer, perspective projection, shape rasterization, HUD text

Key Code Walkthrough

Scene setup (scene.rs) registers physics components on the ECS world and spawns entities with Transform, Velocity, RigidBodyComponent, and ColliderComponent. Five spheres, three cubes, a ground plane, a player entity, and a trigger zone are created -- totaling 11 entities.

let ground = spawn_ground(world);
let spheres = spawn_spheres(world, 5);
let cubes = spawn_cubes(world, 3);
let player = spawn_player(world);
let trigger_zone = spawn_trigger_zone(world);

Main loop (main.rs) runs at 60 FPS using minifb. Each frame:

  1. Reads keyboard input and updates orbit angles or player velocity.
  2. Follows the player with the camera target.
  3. Steps physics -- applies gravity, integrates velocities, clamps to ground.
  4. Detects trigger overlaps.
  5. Clears the framebuffer, renders ground, shadows, trigger zone, objects, and the HUD.

Rendering (render.rs) implements a CPU-only rasterizer. Each shape is projected from world space to screen space using a perspective matrix, then drawn with simple filled-circle or filled-rect routines. Shadow blobs are rendered as darkened ellipses beneath each object.

The HUD displays the current tick count, entity count, active trigger pairs, and frame time using a built-in 5x7 bitmap font.

Source Location

All source files live under examples/3d-demo/src/:

  • main.rs -- entry point, window creation, main loop
  • scene.rs -- entity spawning and physics helpers
  • render.rs -- software rasterizer and projection math
  • font5x7.bin -- bitmap font data for HUD text