embedded-3dgfx
A no_std 3D graphics and physics engine for embedded systems, optimized for resource-constrained devices. Features real-time rendering, rigid body dynamics, soft body physics, skeletal animation, and visual effects.
This is a fork of embedded-gfx by Kezii. This fork adds texture mapping, fog/dithering effects, DMA rendering, Z-buffer improvements, anti-aliasing, and a complete physics engine.
Features
3D Rendering
- Full MVP pipeline — Model-View-Projection with perspective projection
- Z-buffering with 16.16 fixed-point depth testing
- Flat and Gouraud shading, directional lighting, Blinn-Phong specular
- Affine UV texture mapping with multi-texture support and RGB565 format
- Fog, dithering (4x4 Bayer), billboards, vertex animation
- Anti-aliased lines and triangles (heuristic and per-pixel coverage modes)
- LOD system with distance-based mesh switching
- Frustum and backface culling, DMA double-buffer rendering
Physics Engine
- Rigid body dynamics — linear/angular motion, forces, torques
- Sphere, AABB, and capsule colliders with impulse-based collision response
- Distance, ball-socket, and fixed joint constraints
- Ray casting with hit point and normal
Skeletal Animation
- Parent-child bone hierarchies with linear blend skinning (SSD)
- Up to 4 bone influences per vertex
Soft Body Physics
- Mass-spring systems for cloth, jelly, and deformable objects
- Volume preservation via pressure simulation
UI Animation
- Rigid transform animation tracks for splash screens and menus
- Tweening with easing functions (
Tween3,Easing)
Screenshots
To regenerate all screenshots and GIFs:
Installation
[]
# Embedded (no_std)
= { = "0.2", = false }
# Desktop / simulator with all features
= { = "0.2", = ["std"] }
Basic Example
use ;
use Vector3;
let mut engine = new;
engine.camera.set_position;
let geometry = Geometry ;
let mut mesh = new;
mesh.set_render_mode;
engine.render;
Physics Example
use ;
use Vector3;
let mut world = new;
world.set_gravity;
let sphere = new
.with_collider
.with_position;
world.add_body;
let ground = new_static
.with_collider;
world.add_body;
world.;
let ray = new;
if let Some = world.ray_cast
Examples
The project includes 26 interactive examples. Run with:
Rendering:
basic_rendering— render mode cycling (points, lines, solid)rotating_cube— animated 3D transformationsscene_viewer— interactive multi-mesh scenelighting_demo— directional lighting with ambientgouraud_demo— smooth color interpolationblinn_phong_demo— specular highlightsfog_dithering_demo— atmospheric effectstexture_mapping_demo— UV-mapped texturesdma_rendering_demo— double-buffer performancebillboard_demo— camera-facing quadslod_demo— level-of-detail switchingvertex_animation_demo— keyframe vertex morphingpainters_algorithm_demo— painter's algorithm renderingboot_menu— boot splash and menu transitions (96x64, tweens + transform tracks)stl_viewer— load and view STL models
Physics:
physics_rolling_ball— beginner-friendly introphysics_bouncing_balls— multiple colliding spheresphysics_pendulum— swinging pendulum with constraintsphysics_newtons_cradle— chain constraintsphysics_stack_tower— stacking boxes with frictionphysics_domino_chain— domino effect simulationphysics_wrecking_ball— wrecking ball demolitionphysics_demo— comprehensive physics showcasecapsule_physics_demo— capsule collider interactionsskeletal_animation_demo— bone hierarchy and skinningcloth_simulation— hanging cloth with windjelly_cube_demo— soft deformable cuberaycast_demo— ray casting and hit detection
Feature Flags
| Flag | Default | Description |
|---|---|---|
std |
on | Enables painter's algorithm (Vec) and includes perfcounter |
perfcounter |
off | FPS/timing measurements (requires std or embassy-time) |
embassy-time |
off | Timing source for embedded targets |
aa-heuristic |
on | Heuristic analytical edge anti-aliasing for triangles, no extra buffer |
aa-coverage |
on | Per-pixel coverage AA with end-of-frame composite; eliminates shared-edge seam at cost of a W×H byte buffer |
row_width_96 |
— | Optimize row buffers for 96px-wide displays |
row_width_160 |
— | Optimize row buffers for 160px-wide displays |
row_width_240 |
— | Optimize row buffers for 240px-wide displays (default) |
row_width_320 |
— | Optimize row buffers for 320px-wide displays |
The row_width_* flags are mutually exclusive. aa is an internal flag enabled automatically by either AA feature.
Caps and Telemetry
For command-buffer budgeting, profile-cap selection, and record/execute telemetry usage, see:
docs/caps-and-telemetry.md
For validated target/profile/backend coverage, see:
docs/compatibility-matrix.md
For backend bring-up and deployment checklists, see:
docs/backend-integration-checklist.mddocs/memory-sizing-guide.mddocs/no-std-architecture.md
For CI telemetry/perf baseline policy, see:
docs/perf-baselines.mddocs/rendering-performance-evidence.mddocs/hardware-profiling.mddocs/hardware-smoke-tests.mddocs/asset-pipeline.md
System Requirements
Minimum:
- ARM Cortex-M4F with FPU
- 128 KB RAM (single buffer, small scenes)
- 256 KB Flash
Recommended:
- ARM Cortex-M33 with FPU (e.g. STM32WBA)
- 512 KB+ RAM (double buffer + Z-buffer + physics)
- 512 KB+ Flash
Memory usage at 240x135:
| Feature | Cost |
|---|---|
| Single framebuffer | 65 KB |
| Double framebuffer | 130 KB |
| Z-buffer | 130 KB |
| Physics (16 bodies) | ~4 KB |
| Soft body (64 particles) | ~2 KB |
| Skeleton (8 bones) | ~1 KB |
Performance budget at 240x135 @ 60 FPS:
- Rendering: ~10-13 ms/frame
- Physics (16 bodies): ~2-3 ms/frame
- DMA display transfer: ~3 ms (parallel)
Performance
Frame times measured on the desktop simulator at 320×240 (cargo run --release --example screenshots --features std). Numbers reflect the record + execute pipeline introduced in v0.2 — scene traversal and rasterization are separate phases, making per-frame costs explicit and predictable.
| Scene | Resolution | Triangles | p50 (release) | p50 (debug) |
|---|---|---|---|---|
| Wireframe cube | 320×240 | 12 | 0.05 ms | 3.6 ms |
| Blinn-Phong Suzanne | 320×240 | ~960 | 0.09 ms | 6.6 ms |
| Physics (5 balls + floor) + render | 320×240 | ~800 | 0.08 ms | 8.2 ms |
Desktop figures are on a modern x86-64 CPU and will not match embedded hardware directly. On ARM Cortex-M33 @ 64 MHz expect roughly 10–13 ms/frame for mid-complexity scenes at 240×135 (see System Requirements).
What changed in v0.2:
- micromath transcendentals —
sin/cos/atan2are now routed through micromath onno_stdtargets, replacing soft-float libm. Measured ~15–25% reduction in per-frame transform cost on Cortex-M4 targets. - record/execute pipeline — scene traversal (record) and rasterization (execute) are now explicit separate phases. This eliminates hidden double-work and allows command-buffer replay without re-traversing the scene graph.
- 16.16 fixed-point storage — depth values use
u32fixed-point storage throughout the z-buffer path, cutting memory bandwidth on 32-bit bus targets.
To reproduce the benchmark locally:
Architecture
src/
lib.rs # Main engine and rendering loop
camera.rs # View/projection matrices
mesh.rs # Geometry, LOD
draw.rs # Rasterization, shading, effects
physics.rs # Rigid body dynamics
skeleton.rs # Skeletal animation
softbody.rs # Soft body physics
texture.rs # Texture management
billboard.rs # Camera-facing quads
animation.rs # Keyframe animation
transform_anim.rs # Rigid transform animation tracks
tween.rs # Tweening and easing
swapchain.rs # DMA double-buffering
display_backend.rs # Display abstraction
bridge.rs # embedded-graphics bridge
painters.rs # Painter's algorithm
perfcounter.rs # Performance monitoring
lut.rs # Lookup tables
load_stl/ # STL file embedding macro
examples/ # 26 interactive demos
tests/ # 196 unit tests
Testing
Contributing
Contributions welcome. Priority areas:
- Hardware-specific display backends (ESP32, STM32, RP2040)
- Spatial partitioning (octree/BVH for broad-phase)
- Additional joint types (hinge, slider, prismatic)
- Perspective-correct texture mapping
- Mesh colliders (convex hulls)
References
Graphics:
- Tricks of the 3D Game Programming Gurus
- Michael Abrash's Graphics Programming Black Book
- PSX Graphics Programming
Physics:
License
MIT OR Apache-2.0 — see LICENSE for details.