Software RayTracing engine written in C++ without the usage of any libraries.

Software Raytracing Engine

This is a software unidirectional raytracing engine, fully written in C++17, with no dependencies or external libraries used.

How to launch it

If you are using MSVS, you can launch it from the project file. Alternatively, you can build it with CMake

cmake -H. -Bbuild
cmake --build build
./bin/RayTracing

Input

As input, the program uses a scene file, where all properties are listed. Depending on the scene, object files, textures, and skyboxes might also be loaded. Scene path can be passed as an argument value at program start.

Output

The output of the program is a single bpm file, containing a rendered image of a given resolution. BMP image format was chosen because of its simplicity.

Scene loader

In order to render something, we need information about scene. Those are stored in scene file. It is a text file that has several blocks:

  • Options: Here all types of settings are store as a pair of =
  • Object/Light: Each light or object block represents a single entity in the scene.
  • End block: The scene file ends with an end block to indicate that all data has been read.

Features

Multithreading

Ray tracing process for each pixel is a task that can be easily paralleled, so the program splits a scene into a set of 128x128 tiles and then renders them with a number of threads that equals to system thread count.

Anti-Aliasing

After scene was rendered, anti-aliasing may be applied. The process consists of 2 steps: running Sobel filter on rendered image to detect edges. And then launch tile renderer that will rewrite image pixel with color of 4 new rays launched for that pixel.

Sobel filter result 8x zoomed image comparison

Basic shapes

The simplest scene that can be rendered is a scene consisting of base shapes, like Sphere and Plane, and Point or Distant light sources. Here is an example of such a scene.

Here you can see all 4 types of surfaces:

  • Diffuse - Collects info from all visible light sources
  • Phong - Combines three components: ambient, diffuse, specular
  • Reflective - Casts reflected ray for every ray fallen on it
  • Transparent - Using Fresnel model: combines refracted and reflected rays

How Phong illumination system works:

Ambient Diffuse Specular Final

Skybox

On the image below you can see the application of the skyboxes. Skybox is composed of 6 cube textures, and each time ray leaves the scene - we get color from one of those textures

Polygon Meshe

In order to use Polygon Mesh, we have to first load it. There are a lot of object types that can store 3d object data, but the type of my choice was .obj file. It is relatively simple yet powerful enough to implement a full specter of features.

Mesh features

Backface culling

Backface culling is a simple technique that can give a little performance boost at the ray-triangle intersection test. If ray faces 'another side' of triangles, the intersection will not be fully computed. However, if the model has some holes in it, it may give visual artifacts:

Backface culling on (2.1 s) Backface culling off (2.7s)

Acceleration Structures

They do not change anything in visual appearance, however, they can boost performance up to tens of times. It does so by creating a hierarchy of bounding boxes, which allows saving a lot of ray-triangle intersections. Each box may have two ancestor boxes, or store a set of triangles. This way we may text triangles only when the ray intersects the box. Left and Right boxes are separated by SAH - Surface Area Heuristic. This program has an option to visualise those bounding boxes:

Rendered object Low penalty (1) Higher penalty (10)

The only parameter determining AC construction is a penalty. The deeper AC is in the hierarchy, the bigger the minimum amount of triangles it can store. Therefore the total amount of AC will change. However, it doesn't have much impact on performance.
Model above containes 250'000 triangles. Without usage of AC render time was 356 seconds. With AC - only 6 seconds.

Basic Shaders

Mesh consists of polygons (triangles), and if we will draw them as they are we will receive an image that doesn't look nice. To fix it, we may use shaders. The most basic one will smoothen the surface by extrapolating the normal triangle vertices.

Flat shading Vertex shading

Texture maps

The plain object is not very interesting and useful, so we can use texture maps to fix it. A texture map (sometimes called diffuse map) is an image storing information about objects' color. We can get them from texture coordinates, which are associated with each triangle. Also, those coordinates are normalized (from 0 to 1), therefore texture itself can have any size. The bigger the size - the better the quality.

Texture file Render without texture Render with texture

Normal maps

Another tecnique similar to texture map is normal map. It can add to object more small details, without increasing the complexity of geometry. To use the tangent normal map we have to calculate tangent and bitangent for each triangle, and each time we'll need a normal we will transform the vector from the map into world space. In each pixel of such a map 3d vector is encoded, which shows direction of normal in tangent space.
Following 2 images show normal view of object, which means that color of surface shows direction of normal in world space. In upper image we can see that object is smooth, while on picture below surface has much more details in it. It is the effect of normal map.

Specular map

We can add one more map to the object, which is specular map. This map is used for Phong shaded objects and can determine how reflective surface will be.

All 3 maps of the following model:

Texture (diffuse) map Normal map Specular map

And with those 3 image we managed to enhance view of our model without significant performance loss.

Area light

The area light is the thing that can make a scene look much more plausible, but it also makes it much slower. In this engine, every area light source is parallelogram defined by its center position and sides vectors. Light quality is described by the number of samples per side of the parallelogram. So, the bigger the source - the more samples should be used and slower it will run.

Original model Low resolution of light source
Small light source Large light source

Also, if you are additionally interested in code and wish to expore it more, output folder has the call tree generated by Doxygen

Similar Resources

Brand new engine with new and QoL features. Grafex is Psych engine with some additions and Better graphics

Friday Night Funkin' - Graphex Engine Credits: Grafex Mod aka Psych Graphic Rework: Xale - Lead Coding, Artist PurpleSnake - Second Coder Psych Engine

Jan 7, 2023

ORE (OpenGL Rendering Engine) is a rendering engine developed for my college minor project assessment.

ORE (OpenGL Rendering Engine) is a rendering engine developed for my college minor project assessment.

ORE (OPENGL RENDERING ENGINE) What is ORE? ORE(OpenGL Rendering Engine) is a rendering engine with great and easy to use UI that allows the user to lo

Sep 23, 2022

A 2D Physics Engine written in C++, supporting circles and orientable, non-regular convex polygons.

PhysicsEngine A basic physics engine supporting circles and orientable non-regular convex polygons. Oh, and it has undamped springs and strings. Demo

Mar 19, 2022

Vire is a C++ voxel rendering engine. It is written in C++14 and uses OpenGL for graphics.

Vire Vire is a C++ voxel rendering engine. It is written in C++14 and uses OpenGL for graphics. Downloads If you'd just like to just download and try,

Dec 22, 2022

Plugin implementing Kirchhoff rods to simulate any 1D flexible structure

Plugin implementing Kirchhoff rods to simulate any 1D flexible structure

BeamAdapter plugin This SOFA plugin implements a 1-dimensional Finite Element Method (FEM) in the context of coil embolization in neurology. The metho

Nov 24, 2022

A C++ commandline for use in servers and chat software. Provides very simple asynchronous input/output.

A C++ commandline for use in servers and chat software. Provides very simple asynchronous input/output.

commandline A C++ commandline for use in servers and terminal chat software. Provides very simple asynchronous input/output. Supports reading and writ

Dec 20, 2022

Pencil2D is an animation/drawing software for Windows, macOS, Linux, and FreeBSD.

Pencil2D is an animation/drawing software for Windows, macOS, Linux, and FreeBSD. It lets you create traditional hand-drawn animation (cartoon) using both bitmap and vector graphics. Pencil2D is free and open source.

Jan 7, 2023

ZBar Bar Code Reader is an open source software suite for reading bar codes from various sources

ZBar Bar Code Reader is an open source software suite for reading bar codes from various sources

Dec 26, 2022

Dust3D is a cross-platform open-source 3D modeling software

Dust3D is a cross-platform open-source 3D modeling software

Dust3D is a cross-platform open-source 3D modeling software. Auto UV unwrapping, auto rigging with PBR Material support, pose and motion authoring all in one.

Dec 30, 2022
Minimal pathtracer using Vulkan RayTracing
Minimal pathtracer using Vulkan RayTracing

Single File Vulkan Pathtracing Minimal pathtracer using Vulkan RayTracing Environment Vulkan SDK 1.2.162.0 GPU / Driver that support Vulkan Ray Tracin

Dec 21, 2022
Minimal raytracing example with a combination of embree and tinyobjloader
Minimal raytracing example with a combination of embree and tinyobjloader

embree-tinyobj-example minimal raytracing example with a combination of embree and tinyobjloader Requirements CMake (>=3.20) Embree (>=3) OpenMP (Opti

Apr 7, 2022
A fork of Microsoft's D3D12 Raytracing Fallback Layer

D3D12 Raytracing Fallback Layer The D3D12 Raytracing Fallback Layer is a library that emulates the DirectX Raytracing (DXR) API on devices without nat

Sep 13, 2022
PainterEngine is a application/game engine with software renderer,PainterEngine can be transplanted to any platform that supports C
PainterEngine is a application/game engine with software renderer,PainterEngine can be transplanted to any platform that supports C

PainterEngine is a application/game engine with software renderer,PainterEngine can be transplanted to any platform that supports C

Jan 4, 2023
Horde3D is a small 3D rendering and animation engine. It is written in an effort to create an engine being as lightweight and conceptually clean as possible.

Horde3D Horde3D is a 3D rendering engine written in C++ with an effort being as lightweight and conceptually clean as possible. Horde3D requires a ful

Dec 31, 2022
Software ray tracer written from scratch in C that can run on CPU or GPU with emphasis on ease of use and trivial setup
Software ray tracer written from scratch in C that can run on CPU or GPU with emphasis on ease of use and trivial setup

A minimalist and platform-agnostic interactive/real-time raytracer. Strong emphasis on simplicity, ease of use and almost no setup to get started with

Dec 28, 2022
Yocto/GL: Tiny C++ Libraries for Data-Driven Physically-based Graphics
Yocto/GL: Tiny C++ Libraries for Data-Driven Physically-based Graphics

Yocto/GL: Tiny C++ Libraries for Data-Oriented Physically-based Graphics Yocto/GL is a collection of small C++17 libraries for building physically-bas

Dec 27, 2022
This is a openGL cube demo program. It was made as a tech demo using PVR_PSP2 Driver layer GPU libraries.

OpenGL Cube Demo using PVR_PSP2 Driver layer GPU libraries This is a openGL cube demo program. It was made as a tech demo using PVR_PSP2 Driver layer

Oct 31, 2021
OpenGL Object Loading can load virtually every 3d.obj file you can find on the internet, without using another object loading library
OpenGL Object Loading can load virtually every 3d.obj file you can find on the internet, without using another object loading library

OpenGL Object Loading can load virtually every 3d.obj file you can find on the internet, without using another object loading library (assimp for example). The program can load Object with 12M+ triangles and more

Dec 18, 2022
Open 3D Engine (O3DE) is an Apache 2.0-licensed multi-platform AAA Open 3D Engine
Open 3D Engine (O3DE) is an Apache 2.0-licensed multi-platform AAA Open 3D Engine

Open 3D Engine (O3DE) is an Apache 2.0-licensed multi-platform 3D engine that enables developers and content creators to build AAA games, cinema-quality 3D worlds, and high-fidelity simulations without any fees or commercial obligations.

Jan 7, 2023