Skip to content

A 2D raycasting and rendering simulator written in C++ using the SFML library for drawing graphics.

Notifications You must be signed in to change notification settings

iikerm/2D-raycasting-sim

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

2D Raycasting and Rendering Simulator

What does the title mean?

The main idea behind this project is to make a program that can take a 'maze' composed of different objects and cast various rays of simulated light from a 'camera' that will collide in one way or another with these objects in the maze as the user moves the camera across the window. These collisions can then be interpreted according to their distance away from the camera in order to produce a dynamic image (a render) that represents what the camera is seeing through its angle of vision.

How does this program work?

It is made up of 3 main components:

Rays 'of light'

A ray (of light in this case) represents a line going from point A to point B. This line is made up of individual points where we can check if the ray of light has collided with a solid object (i.e. the point is inside the object), and if it has, we know that the ray must only travel up to this specific point.

Rays can be rotated (by applying matrix multiplication with a rotation matrix), and moved in any direction (by adding/subtracting a 2-Dimensional offset to all the points in the ray).

The Camera

This is an object that groups rays together so that they all start from a common point. It is represented by a circle and the user of the program can control its movements by using the WASD keys, and its angle of rotation can be increased using the ↑ Up arrow, and decreased using the ↓ Down arrow.

Some optimizations, like ordering the vector of solid objects according to their distance away from the camera to improve ray collision probability, or drawing all the rays as an array of triangles instead of hundreds of lines, have been done inside some methods of this class.

The Renderer class

This class is a simpler class, meant to be associated with a Camera object and to render (as its name implies) what this object is 'seeing'. It does this by taking the distances away from the camera where each of its rays has found a collision. Using these distances, and comparing them with a reference distance is how different shades of a color (in the case of the image below: red) are produced, where darker tones indicate an object that is further away from the camera.

All this information is represented in a view (which in the image below can be found in the top right corner), which is effectively a rendered simulation of what the camera object is 'seeing' through its rays.

Program images:

imagen

  

The maze that generated the solid objects in the image above is currently hardcoded inside the main() function in src/main.cpp:

hardcoded maze of 1s and 0s

Parameter adjusting

One aim of this program was (among others) to see the differences in output quality produced when changing a parameter out of a set of adjustable elements among the various objects. You will find indicated below what each parameter does, and where they are found in the code so that one can play around with them.

Camera View Angle (main.cpp)

This parameter is set by default to 50° (degrees), and it changes how wide the camera spreads its rays (up to a maximum of 360° and minimum of 1°).

Changing this parameter doesn't directly affect performance (because increasing it just makes rays be more spaced out), but if it is increased without doing so with the camera's ray amount as well, the quality of the output decreases.

Camera Ray Amount (main.cpp)

This parameter is set by default to 200, and it specifies the amount of rays (spaced evenly) that will be present inside the camera's view angle.

This parameter is inversely proportional to performance (i.e. increasing it decreases performance), however only increases at lower values are noticeable in terms of quality. For my specific screen size, any further increases after 200 rays were barely noticeable in terms of quality, but they were performancewise.

Ray point density (Ray.hpp)

This parameter specifies the number of points where the ray can check for a collision for every 100px of ray that is drawn. It is set by default to 60 points per 100px.

It is inversely proportional to performance (i.e. increasing it decreases performance) and an increase at lower values has a big impact on the quality of the output produced, although after a certain threshold (around 30-40) any further increase is almost unnoticeable in terms of quality increase.

Program dependencies

This program was made and tested using the SFML library in version 2.6.1.

Note

When writing this, the latest SFML version available is v3.0.0, but there should be no problems when compiling with said newer version.

To install it, in Ubuntu and other linux distros with the apt packet manager, one can use:

$ sudo apt install libsfml-dev

How can you try this program?

This was developed using Ubuntu 24.04, so the binaries available in the bin folder can be downloaded and executed in similar operating systems using:

2d-raycasting-sim/bin$ chmod +x main
2d-raycasting-sim/bin$ ./main

In case you want to tweak the program's parameters, or change it for any other reason, I have included a makefile, which can be executed using:

2d-raycasting-sim$ make

After this, the binary called main in the bin folder will reflect the changes you made to the code.

Note

The compilation process in windows is more complex than the one for ubuntu, but detailed instructions are included in the file COMPILE_WIN.md.

About

A 2D raycasting and rendering simulator written in C++ using the SFML library for drawing graphics.

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published