Back to École 42 Projects

cub3d

EN | FR
Your browser does not support SVG

Visual representation of the raycasting process and cub3d architecture

Project Essence

cub3d is a graphics project that introduces you to raycasting, a rendering technique that creates a 3D perspective from a 2D map. Inspired by the groundbreaking game Wolfenstein 3D, this project challenges you to build your own simplified 3D game engine from scratch.

The Core Challenge

Create a 3D graphical representation of a maze from a 2D map, where:

  • The player can navigate through the maze in first-person perspective
  • Walls are rendered with different colors or textures based on their orientation
  • The program reads map configurations from files with a specific format
  • The rendering must be smooth and efficient, with proper collision detection

This project tests your understanding of graphics programming, mathematical concepts in 3D rendering, and efficient algorithm implementation.

cub3d challenges you to think about:

  • How to translate 2D map data into a 3D perspective using raycasting
  • How to handle user input for smooth movement and camera rotation
  • How to optimize rendering for performance while maintaining visual quality
  • How to implement texturing and lighting effects to enhance visual appeal
  • How to structure a complex graphics application with clean, maintainable code

Why This Matters in the Real World

The raycasting and 3D graphics techniques you'll master in cub3d have significant real-world applications:

  • Game Development: While modern games use more advanced techniques, raycasting principles form the foundation of 3D rendering pipelines used by companies like Epic Games (Unreal Engine) and Unity Technologies. Understanding these fundamentals makes you a more effective developer when working with any graphics system.
  • Architectural Visualization: Firms like Autodesk and Trimble use similar ray-based rendering techniques for creating interactive walkthroughs of building designs, allowing clients to experience spaces before construction begins.
  • Medical Imaging: Volume rendering in medical software by companies like Siemens Healthineers and GE Healthcare uses ray-based techniques to visualize 3D data from CT and MRI scans, helping doctors diagnose conditions and plan surgeries.
  • Autonomous Vehicles: Companies like Tesla and Waymo use ray-based sensor simulation for training self-driving systems, modeling how lidar and radar signals interact with the environment.
  • Virtual Reality: The spatial rendering and camera control techniques you'll implement are directly applicable to VR development at companies like Meta (Oculus) and Valve, where creating convincing 3D environments is essential.

The global computer graphics market is projected to reach $376 billion by 2027. By mastering the fundamental principles in cub3d, you're building skills that are in high demand across multiple industries where spatial visualization and interactive 3D environments are increasingly important.

100/100
Project Score
MiniLibX
Graphics Library
Raycasting
Rendering Technique
High
Complexity

Mental Models

To approach cub3d effectively, consider these mental models that will help you conceptualize the raycasting process and 3D rendering:

The Flashlight Model

Imagine the player holding a flashlight that casts rays in different directions. Each ray travels until it hits a wall, and the distance it travels determines how tall that slice of wall appears on screen.

This model helps you understand the core principle of raycasting: casting rays from the player's position and using the distances to walls to create the illusion of depth.

The Camera Film Model

Think of your screen as a vertical film strip in front of the player. Each vertical line on the screen corresponds to a ray cast into the world, and what appears on that line depends on what the ray encounters.

This perspective clarifies how the 2D screen relates to the 3D world and why we cast one ray per vertical screen column.

The Grid Navigation Model

Visualize the game world as a grid where the player moves from cell to cell. Walls occupy entire cells, and the player navigates through empty cells while avoiding collisions with walls.

This model simplifies collision detection and map representation, making it easier to reason about player movement and ray intersections.

These mental models will help you approach the project not just as a coding exercise, but as a graphics system design challenge that requires thinking about spatial relationships, perspective, and efficient rendering techniques.

Key Concepts

Before diving into implementation, make sure you understand these fundamental concepts:

Historical Context: The Evolution of 3D Rendering

The raycasting technique you'll implement in cub3d has a rich history in computer graphics:

  • Early Beginnings (1970s): The concept of raycasting emerged from ray tracing research at the University of Utah, where pioneers like Martin Newell and Jim Blinn were developing techniques to create realistic 3D images. However, the computational demands made real-time applications impossible on hardware of that era.
  • Wolfenstein 3D Revolution (1992): John Carmack at id Software implemented an optimized raycasting engine that could run in real-time on consumer PCs, creating the first truly immersive first-person shooter. This breakthrough demonstrated that clever algorithmic shortcuts could create convincing 3D environments without requiring full 3D geometry processing.
  • The Transition Era (1993-1996): Following Wolfenstein 3D's success, games like DOOM expanded on raycasting principles while beginning to incorporate more advanced techniques. This period represented a bridge between pure raycasting and full 3D polygon rendering.
  • Modern Applications (Present): While polygon-based rendering dominates modern games, raycasting principles have found new applications in fields like medical imaging, architectural visualization, and physics simulations. The recent resurgence of ray tracing in real-time graphics (NVIDIA RTX, AMD Ray Accelerators) represents a return to ray-based rendering, albeit with vastly more sophisticated implementations.
  • Educational Value: Raycasting remains one of the most accessible entry points to 3D graphics programming, offering a perfect balance of mathematical elegance and practical implementation challenges without requiring advanced linear algebra or graphics hardware knowledge.

By implementing cub3d, you're connecting with this rich heritage and gaining insights into fundamental rendering concepts that have shaped computer graphics for decades.

1. Raycasting Fundamentals

Understanding the core rendering technique:

  • Ray Casting: Projecting rays from the player's position to determine wall distances
  • Field of View (FOV): The angular extent of the visible world
  • Projection Plane: The virtual screen where the 3D world is projected
  • Wall Height Calculation: Converting distance to wall height using projection formulas

2. Graphics Programming

Working with the MiniLibX library:

  • Window Management: Creating and controlling the game window
  • Image Manipulation: Creating, modifying, and displaying images
  • Color Handling: Working with RGB colors and pixel manipulation
  • Double Buffering: Preventing screen flickering during rendering

3. Vector Mathematics

Essential math for 3D graphics:

  • Vector Operations: Addition, subtraction, scaling, and normalization
  • Trigonometry: Using sine and cosine for direction and rotation
  • Distance Calculation: Computing distances between points
  • Intersection Detection: Finding where rays intersect with walls

4. Texturing and Rendering

Enhancing visual quality:

  • Texture Mapping: Applying images to walls based on their orientation
  • Texture Coordinates: Determining which part of a texture to display
  • Mipmapping: Optimizing texture quality at different distances
  • Rendering Pipeline: The sequence of operations to generate each frame

5. Game Loop and Input Handling

Creating an interactive experience:

  • Game Loop: The continuous cycle of update and render
  • Input Processing: Handling keyboard and mouse events
  • Movement Physics: Implementing smooth player movement
  • Collision Detection: Preventing the player from walking through walls

Progress Checkpoints: Test Your Understanding

Before proceeding with your implementation, make sure you can answer these questions:

Raycasting Fundamentals

  1. How would you calculate the distance from the player to a wall using the DDA algorithm?
  2. What causes the fisheye effect in raycasting, and how do you correct it?
  3. How do you determine which side of a wall (N/S/E/W) a ray has hit?

Graphics and Rendering

  1. How do you convert a wall distance to a height on the screen?
  2. How would you calculate the exact position on a wall texture that corresponds to where a ray hit?
  3. What's the relationship between the player's field of view and the width of the screen?

Game Architecture

  1. How would you structure your code to separate the raycasting logic from the rendering code?
  2. What data structure would be most appropriate for storing and accessing your game map?
  3. How would you implement smooth movement and rotation that's consistent regardless of frame rate?

If you can confidently answer these questions, you have a solid foundation for implementing cub3d. If not, revisit the relevant concepts before proceeding.

Implementation Approach

Here's a structured approach to help you implement the cub3d project:

1. Project Architecture

Before writing code, plan your game's architecture:

  • Define the main components: map parser, raycaster, renderer, input handler
  • Design data structures to represent the map, player, and rendering state
  • Establish clear interfaces between components to maintain modularity
  • Create a logical file organization that reflects your architecture

Comparative Approaches: Raycasting Implementation Strategies

There are several ways to implement the raycasting algorithm for cub3d, each with different trade-offs:

Raycasting Approach Advantages Disadvantages Best When
DDA (Digital Differential Analysis)
Step through the grid using normalized ray direction
  • Highly efficient algorithm
  • No trigonometric functions in inner loop
  • Consistent performance regardless of view angle
  • More complex to implement
  • Harder to understand intuitively
  • Requires careful handling of edge cases
You prioritize performance and want a solution that scales well to larger maps
Angle-Based Approach
Cast rays at regular angular intervals
  • More intuitive to understand
  • Directly maps to the mental model of rays
  • Easier to implement initially
  • Less efficient due to trigonometric functions
  • Can have performance issues at certain angles
  • More prone to floating-point precision issues
You want a more straightforward implementation and are willing to sacrifice some performance
Hybrid Approach
Precompute angles and use optimized intersection tests
  • Good balance of performance and clarity
  • Avoids trigonometric functions in inner loops
  • More flexible for extensions
  • More complex overall architecture
  • Requires careful optimization
  • More memory usage for lookup tables
You plan to add more features like sprites or dynamic lighting and need a flexible foundation

Your choice should reflect your priorities between performance, code clarity, and extensibility. Many successful implementations combine elements from different approaches.

Architecture Questions

  • How will you represent the game map in memory?
  • What data structure will you use to store wall textures?
  • How will you organize your code to separate graphics from game logic?
  • What will be the flow of data through your game's components?
  • How will you handle different aspects of rendering (walls, floor, ceiling)?

2. Implementation Strategy

A step-by-step approach to building your game:

Phase 1: Foundation

Build the core infrastructure:

  • Set up the MiniLibX environment
  • Create window management functions
  • Implement basic event handling
  • Establish a simple game loop

Phase 2: Map System

Create the game world:

  • Implement map file parsing
  • Validate maps according to requirements
  • Create data structures to represent the map
  • Implement a 2D map renderer for debugging

Phase 3: Basic Raycasting

Implement the core rendering technique:

  • Create the raycasting algorithm
  • Calculate wall distances and heights
  • Render simple untextured walls
  • Implement different colors based on wall orientation

Phase 4: Player Movement

Add interactivity:

  • Implement player movement controls
  • Add camera rotation
  • Implement collision detection
  • Create smooth movement physics

Phase 5: Texturing

Enhance visual quality:

  • Load and manage texture images
  • Implement texture mapping on walls
  • Calculate texture coordinates
  • Apply textures based on wall orientation

Phase 6: Refinement

Polish your implementation:

  • Optimize rendering performance
  • Add floor and ceiling rendering
  • Implement proper error handling
  • Add finishing touches to the UI

3. Code Organization

A suggested file structure for your project:

include/ cub3d.h # Main header with structures and function prototypes raycaster.h # Raycasting-related definitions renderer.h # Rendering-related definitions map.h # Map-related definitions src/ main.c # Entry point and game loop init.c # Initialization functions parser/ map_parser.c # Functions for reading and validating maps texture_parser.c # Functions for loading textures raycaster/ raycaster.c # Core raycasting algorithm ray_utils.c # Helper functions for ray calculations renderer/ renderer.c # Main rendering functions wall_renderer.c # Wall-specific rendering texture.c # Texture mapping functions player/ movement.c # Player movement and physics collision.c # Collision detection camera.c # Camera and field of view handling utils/ math_utils.c # Mathematical utility functions error.c # Error handling functions memory.c # Memory management utilities Makefile # Build configuration

4. Testing Strategy

Approaches to verify your implementation:

  • Create a suite of test maps with different layouts and features
  • Implement a debug mode that shows the 2D map and ray intersections
  • Test with various movement patterns to verify collision detection
  • Measure frame rates to ensure performance meets requirements
  • Check for memory leaks using tools like Valgrind
  • Test edge cases like very large maps or unusual player positions

Common Pitfalls

Be aware of these common challenges when working on cub3d:

1. Raycasting Implementation Issues

  • Fisheye Effect: Distortion caused by measuring direct distances instead of perpendicular distances
  • Wall Orientation: Incorrectly determining which wall face (N/S/E/W) was hit
  • Precision Errors: Floating-point inaccuracies leading to visual artifacts
  • Performance Bottlenecks: Inefficient ray calculations causing low frame rates

2. Texture Mapping Challenges

  • Texture Stretching: Improper scaling of textures on walls
  • Texture Coordinates: Calculating incorrect x-coordinates within textures
  • Memory Management: Inefficient handling of texture data
  • Texture Alignment: Misalignment at corners or edges

3. Player Movement and Collision

  • Wall Clipping: Player passing through walls due to inadequate collision detection
  • Movement Jitter: Uneven or jerky player movement
  • Rotation Issues: Incorrect implementation of camera rotation
  • Speed Consistency: Movement speed varying with frame rate

Debugging Tips

To overcome common challenges:

  • Implement a 2D top-down view that shows the map, player position, and rays
  • Add visual indicators for ray intersections and wall orientations
  • Create a debug mode that displays numerical values for distances and angles
  • Test with simple, controlled environments before moving to complex maps
  • Use frame timing tools to identify performance bottlenecks
  • Implement step-by-step visualization of the raycasting process

Debugging Scenarios

Here are some common issues you might encounter and how to approach debugging them:

Scenario 1: Fisheye Distortion

Symptoms: Walls appear curved or bulging, especially at the edges of the screen; objects look unnaturally wide when not in the center of view.

Debugging Approach:

  • Verify you're using perpendicular distance (ray length × cos(angle)) rather than direct ray length
  • Add a visualization that shows both the raw and corrected distances
  • Test with a perfectly square room and check if walls appear flat
  • Implement a grid overlay on the 3D view to check for distortion
  • Verify your angle calculations in the ray casting loop

Scenario 2: Texture Mapping Issues

Symptoms: Textures appear stretched, compressed, or misaligned; texture coordinates jump or flicker when moving.

Debugging Approach:

  • Add a debug overlay showing the calculated texture x-coordinate for each vertical strip
  • Implement a simple test texture with a numbered grid to easily identify mapping issues
  • Verify the exact point where the ray hits the wall (not just which wall cell)
  • Check for floating-point precision issues in your texture coordinate calculations
  • Test texture mapping with walls at different distances to ensure consistent scaling

Scenario 3: Performance Problems

Symptoms: Low frame rates; stuttering movement; increasing lag with larger maps or more complex scenes.

Debugging Approach:

  • Add frame time measurements to identify which parts of the rendering pipeline are slowest
  • Profile your code to find hotspots (functions that consume the most CPU time)
  • Check for redundant calculations in your inner rendering loops
  • Verify you're not recalculating constants inside loops
  • Implement progressive rendering for debugging (e.g., render every 10th column first)

Learning Outcomes

Completing cub3d will equip you with valuable skills that extend far beyond the project itself:

Technical Skills

You'll develop expertise in:

  • Graphics programming fundamentals
  • Raycasting and 3D rendering techniques
  • Vector mathematics and trigonometry
  • Texture mapping and image manipulation
  • Optimization strategies for real-time graphics

Game Development

You'll gain insights into:

  • Game loop architecture
  • Player movement and camera systems
  • Collision detection algorithms
  • Level design and map representation
  • Real-time rendering pipelines

Software Design

You'll strengthen your approach to:

  • Structuring complex, multi-component systems
  • Managing state in interactive applications
  • Balancing performance with code clarity
  • Designing modular, maintainable architectures
  • Implementing efficient algorithms

Beyond the Project: Career Applications

The skills you develop in cub3d have direct applications in professional settings:

Game Development
The fundamentals of 3D rendering apply to modern game engines
Computer Graphics
The mathematical principles extend to advanced rendering techniques
Simulation
Similar techniques are used in scientific and industrial simulations
Virtual Reality
The concepts of 3D perspective and camera control are fundamental to VR

Reflection Questions

  • How has this project changed your understanding of 3D graphics and rendering?
  • What aspects of raycasting did you find most challenging, and how did you overcome them?
  • How would you approach this project differently if you were to start over?
  • What optimization techniques were most effective in improving your game's performance?
  • How might you extend this project to create a more complex game or visualization tool?

A Foundation for Graphics Programming

cub3d provides a unique opportunity to understand 3D graphics from first principles, without the abstraction layers of modern game engines. By implementing raycasting yourself, you gain insights into the fundamental challenges and solutions in computer graphics that remain relevant even as technology evolves.

This project bridges the gap between theoretical knowledge and practical implementation, giving you both the mathematical understanding and the programming skills needed to work with more advanced graphics systems. Whether you pursue game development, scientific visualization, or other fields involving computer graphics, the deep understanding you develop in cub3d will serve as a solid foundation.

Going Further: Resources for Deeper Understanding

If you want to explore the concepts in cub3d more deeply, here are some valuable resources:

Books and Documentation

  • "Game Engine Black Book: Wolfenstein 3D" by Fabien Sanglard - Detailed analysis of the original Wolfenstein 3D engine
  • "Tricks of the 3D Game Programming Gurus" by André LaMothe - Covers raycasting and other 3D rendering techniques
  • "Real-Time Rendering" by Tomas Akenine-Möller et al. - Comprehensive guide to modern graphics techniques

Online Resources

  • Lode's Computer Graphics Tutorial - Excellent raycasting tutorial with step-by-step explanations
  • Permadi's Raycasting Tutorial - Classic tutorial on raycasting fundamentals
  • Wolfenstein 3D's Source Code - Available online with commentary explaining the original implementation

Advanced Topics to Explore

  • Sprite Rendering - Adding 2D sprites to your 3D world for enemies, items, etc.
  • Floor and Ceiling Casting - Extending raycasting to render textured floors and ceilings
  • Lighting Effects - Implementing dynamic lighting, shadows, and fog effects

These resources will help you build on the foundation you've established in cub3d and develop a deeper understanding of 3D graphics programming.