Skip to content

Latest commit

 

History

59 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Esker

A software renderer written from scratch in Go, in the spirit of the original Quake engine.

An esker is a ridge of sand and gravel left behind by a river that ran beneath a glacier — a landform made of a path. Northern Minnesota is full of them.

Coordinate System

left = x- right = x+ up = y+ down = y- forward = z- back = z+

1 unit = 1 meter

What this is

Every pixel goes through math I derived myself. There is no graphics API doing 3D work here: Ebitengine provides a window and a way to push a buffer of bytes onto the screen, and nothing else. That is the same role DirectDraw played for WinQuake in 1996.

The point is not to produce a fast or complete engine. The point is to understand the pipeline well enough to rebuild it from nothing — transforms, projection, clipping, rasterization, depth, texture mapping — with the reasoning behind each stage worked out on paper first.

Non-goals

  • Performance parity with anything modern
  • OpenGL, Vulkan, or any hardware 3D path
  • Being a usable game engine
  • Copying the Quake source (reading it is fine, and mostly comes after the fact)

Approach

Derive what follows from the math. Read the source for what doesn't.

The transform pipeline, projection, clipping, depth buffering, and rasterization are all consequences of linear algebra and analytic geometry, so those get worked out from first principles. BSP trees, the potentially-visible set, and the Pentium FDIV interleave were solutions to a specific machine and a specific deadline — those get read about, understood, and then reimplemented in my own terms.

Roadmap

Each milestone puts something on screen.

Getting pixels

  • Project setup, Ebitengine window
  • Owned framebuffer — byte slice, SetPixel, blit once per frame
  • Clear to color, plot a pixel, pin down coordinate system orientation
  • Line drawing (Bresenham)

The pipeline — wireframe

  • Vec3, Mat4 — port up a dimension from the existing 2D library
  • Hardcoded cube: 8 vertices, 12 edges
  • Model → world → view → screen, drawing after each stage
  • Perspective projection
  • Free-look camera (WASD + mouse)
  • Milestone: fly around a wireframe cube

Filled geometry

  • Triangle rasterization, flat-shaded
  • Backface culling
  • Depth buffer
  • Near-plane clipping
  • Milestone: solid cube that correctly occludes itself

Surfaces

  • Mesh loading from file -- kind of done
  • Affine texture mapping — done wrong deliberately, to see the warping
  • Perspective-correct texture mapping
  • Static lighting — face normals, dot product against a light direction
  • Milestone: a textured, lit room to walk through

Making it a game

  • Load a real Quake .bsp map
  • BSP traversal for draw order
  • Collision — player AABB, sliding along planes
  • Gravity, jumping, movement feel
  • Milestone: Quake movement in a Quake map

Stack

  • Go — the language I know well enough to spend my debugging attention on the math instead of the memory
  • Ebitengine — window and blit target only

References

  • Michael Abrash, Graphics Programming Black Book — the contemporaneous account of these problems being solved
  • id Software, Quake source (GPL, 1999) — read after getting stuck, not before

License

MIT

Screenshots

interior shot

exterior shot

About

Quake engine with lisp integration

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages