Raycaster Engine
A pseudo-3D renderer that transforms a 2D environment into an immersive first-person view, inspired by the classic Wolfenstein 3D.
Built from scratch using C and Raylib, this project explores the fundamentals of software rendering. The raycasting technique creates the illusion of 3D by casting rays from the player’s viewpoint and calculating wall heights based on distance.
How It Works
Raycasting is a rendering technique that was popularized by Wolfenstein 3D in 1992. Unlike true 3D rendering, raycasting works by casting rays from the player’s position for each vertical stripe of the screen. When a ray hits a wall, we calculate the distance and use that to determine how tall to draw the wall slice.
The beauty of this approach is its simplicity and speed—it was fast enough to run on early 90s hardware while creating a convincing 3D illusion.
Technical Implementation
DDA Algorithm
I implemented the Digital Differential Analyzer (DDA) algorithm for efficient ray-wall intersection detection. This algorithm steps through the grid one cell at a time, checking for wall collisions along the way.
Texture Mapping
The renderer supports textured walls, which adds significant visual depth to the environment. Each wall slice samples from a texture based on where exactly the ray hit the wall.
Player Movement
Smooth player movement with collision detection ensures you can’t walk through walls. The controls feel responsive and natural.
Key Features
- DDA algorithm for efficient ray-wall intersection
- Texture mapping system for wall surfaces
- Smooth player movement with collision detection
- Cross-platform build system using CMake
What I Learned
This project deepened my understanding of:
- Computer graphics fundamentals
- Linear algebra and trigonometry in practice
- Low-level optimization techniques
- Memory management in C
- Build systems and cross-platform development
Building the Project
The project uses CMake for cross-platform builds:
mkdir build && cd build
cmake ..
make
./raycaster
Raylib is used as the window manager and graphics context, making it easy to handle input and draw to the screen without getting bogged down in platform-specific code.