Skip to content
CommunityPokePublic

About

A 3D game engine written in pure PowerShell — software-rasterized, z-buffered ASCII/ANSI rendering for Windows Terminal

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PS3D — a 3D game engine in pure PowerShell

A real-time 3D engine implemented entirely in .ps1 files — no modules, no native dependencies, no NuGet packages. It does software rasterization of triangle meshes into a depth-buffered ASCII/ANSI frame buffer and draws it in Windows Terminal (or any ANSI-capable console) at interactive frame rates.

Features

  • 3D math pipeline (src/PS3D.Math.ps1) — Vec3/Vec4/Mat4 classes: dot/cross/lerp, 4×4 multiply, translation/rotation/scale, perspective projection, yaw/pitch camera with a view matrix and movement basis.
  • Rendering pipeline (src/PS3D.Renderer.ps1) — software rasterizer:
    • view-space backface culling and flat-shaded directional lighting
    • near-plane triangle clipping (Sutherland–Hodgman, view space)
    • perspective divide → NDC → screen space
    • barycentric triangle fill into a z-buffered char/light buffer
    • 11-step ASCII brightness ramp ( .:;-=+*#%@) or ANSI true-colour output
    • optional depth-tested wireframe mode
  • Meshes (src/PS3D.Mesh.ps1) — built-ins cube, pyramid, gem (icosahedron), torus, sphere, plus a Wavefront OBJ loader (v/f, n-gon fan triangulation, negative indices, auto-recentre/scale, auto-orient).
  • Interactive demo loop (Start-PS3D.ps1) — fly-around camera, toggles, FPS counter, HUD, and a headless render mode for CI/validation.
  • Tests (tests/Invoke-SmokeTest.ps1) — 30 assertions covering the math, OBJ parsing, clipping, and end-to-end rasterization.

Requirements (Windows)

Requirement Notes
Windows 10/11 any edition
Windows Terminal (recommended) full ANSI + UTF-8 support, best colours
PowerShell 7 (pwsh) — recommended much faster than 5.1; get it via winget install Microsoft.PowerShell
or Windows PowerShell 5.1 ships with Windows; works, just slower

Classic conhost.exe also works on Windows 10 1709+ (it understands the ANSI escapes used here), but Windows Terminal looks and feels better.

Launch

# PowerShell 7 (recommended)
pwsh -File .\Start-PS3D.ps1

# Windows PowerShell 5.1
powershell -ExecutionPolicy Bypass -File .\Start-PS3D.ps1

# or just double-click
PS3D.bat

Examples:

pwsh -File .\Start-PS3D.ps1 -Mesh sphere -Width 120 -Height 44
pwsh -File .\Start-PS3D.ps1 -Mesh .\examples\shuttle.obj -Fov 75
pwsh -File .\Start-PS3D.ps1 -Mesh cube -Wireframe -NoColor
pwsh -File .\Start-PS3D.ps1 -Mesh C:\models\teapot.obj

Controls

Key Action
← → ↑ ↓ look around (yaw / pitch)
W S move forward / back
A D strafe left / right
R F move up / down
+ - dolly in / out
space toggle auto-rotate
V toggle wireframe / filled
C toggle ANSI colour
L toggle lighting
N P next / previous built-in mesh
H help screen
Q / Esc quit

Options

-Mesh <name|path>   builtin mesh or .obj file        (default: torus)
-Width -Height      framebuffer size in chars        (default: console size)
-Fov <deg>          vertical field of view           (default: 60)
-Dist <units>       initial camera distance          (default: 4.2)
-Speed <rad/s>      auto-rotate speed                (default: 0.8)
-Fps <n>            frame-rate cap                   (default: 30)
-Wireframe          depth-tested wireframe mode
-NoColor            disable ANSI true-colour shading
-NoHud              hide the status line
-NoCulling          show back faces (for inside-out OBJ files)
-SpinX <factor>     tumble rate around X             (default: 0.7)
-Headless           render without a console UI
-Frames <n>         headless frame count
-OutFile <path>     headless: write final frame text

How it works

vertices ──► model·view matrix ──► view space
         ──► backface cull + directional lighting (face normal)
         ──► near-plane clip
         ──► perspective matrix → w-divide → NDC → screen space
         ──► barycentric fill: char + z-buffer + light level
         ──► one StringBuilder → a single Console::Write per frame

Per-pixel cost is the bottleneck (this is interpreted PowerShell, not a GPU): expect roughly 8–20 fps at 90×40 depending on triangle count and host. Tips for speed:

  • use PowerShell 7, not 5.1 (it is several times faster in these loops)
  • shrink the buffer: -Width 80 -Height 32
  • -Wireframe mode is much cheaper than filled triangles
  • fewer polygons help: built-ins are tuned to be light; huge OBJ files will crawl

Headless / CI mode

Renders frames without needing a console and writes the last frame as text — used by the test suite and handy on CI machines:

pwsh -File .\Start-PS3D.ps1 -Headless -Frames 30 -Mesh torus -OutFile frame.txt
pwsh -File .\tests\Invoke-SmokeTest.ps1     # 30-assertion smoke test

Limitations

  • Flat shading only (no per-vertex normals, no Gouraud/Phong, no textures).
  • Near-plane clipping only; triangles are not clipped against the screen edges (they are cheaply bounding-box clamped instead).
  • OBJ loader reads v/f records only — vn/vt/materials are ignored.
  • Interactive input requires a real console; use -Headless on CI/redirected output.
  • Console glyphs are ~2× taller than wide; the projection compensates, but extreme aspect ratios still look stretched.
  • It's PowerShell: frame times are tens of milliseconds, not microseconds.

Layout

ps3d/
├── Start-PS3D.ps1          entry point + interactive/headless loop
├── PS3D.bat                double-click launcher (Windows PowerShell)
├── src/
│   ├── PS3D.Math.ps1       Vec3/Vec4/Mat4, projection, camera
│   ├── PS3D.Mesh.ps1       Mesh class, built-ins, OBJ loader
│   └── PS3D.Renderer.ps1   z-buffer rasterizer, ANSI composer
├── examples/               cube.obj, shuttle.obj
└── tests/Invoke-SmokeTest.ps1

About

A 3D game engine written in pure PowerShell — software-rasterized, z-buffered ASCII/ANSI rendering for Windows Terminal

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages