Highlights

Description

A 3D engine written in C++ with the ambition to perform real-time ray tracing on CPU.

Capabilities:

  • Transparency
  • Glare
  • Refraction dependent on the refractive index of the material
  • Reflection
  • Optimized trigonometry with Taylor polynomials
  • Render cubes and half-cubes
  • Render exclusively on the CPU
  • Multi-threaded
  • 100 fps in 150x100 px, 1 fps in 1920x1080 px

In order to simplify computations, the Ray Tracing part only uses one ray per pixel. This is configurable, but requires more compute power.

The textures are from Minecraft 1.15.

This project allowed me to render pictures I still use today.

Context

When Minecraft with RTX (now Minecraft Bedrock Edition) was announced in 2020, I felt it would be interesting to create a new engine with simple algorithms.

I decided to restrict myself to CPU in the first place to keep the project simple.

This was not the first 3D engine I made: I started with a simple sort each face by z-index, then draw the image with a certain matrix transformation application. Then, I wrote a BASIC Casio program to display simple shapes on a Graph-35+.

I chose Qt because of its familiarity and the ease with which it allows pixel-by-pixel painting without having to learn Windows-specific events.

Later, I moved the project to CMake and Wingdi in order to try the Windows way of drawing. Then, I tried OpenCL to utilize the GPU for ray computing, but not actual rendering. The Qt version is still more mature, though.

Overview

2020

3 cubes in an L shape with faces red, blue and green on the axis X, Y and Z. Logo of the application.
RGB test on XYZ axis.
6 cubes with Minecraft textures: two types of wood, one stone, one transparent glass, one green tinted glass, one glowstone.

2021

MirrorsInfinite mirrors
A glowstone in yellow reflects itself in two mirrors. The mirrors are almost facing each other.
The glowstone is visible by reflection in the two mirrors, and directly.
An infinite mirror with stone above and below. The edge of the mirror are repeated almost indefinitely.
The infinite mirror is limited by the view distance and the walls above and below.
Real time refreshLogo
The image is split in two. The right part is the old frame. The left part is the new frame. The camera moved, so the result of the ray tracing is visible by the line sweeping the window from left to right.
The threads are sweeping the window with new colors.
A J and L drawn in blocks. The blocks' faces are rendered in RGB and their complementary colors depending on the orientation of the face.
Logo I sometimes use.
RefractionWater
View from inside a glass at index 1.5.
A block of water is in the bottom right corner. It has the effect to add blue filter and diffraction on the objects behind it.
A block of water with a refractive
index of 1.33 illustrates diffraction.
RefractionWater
Showcase of camera entering glass. The glass acts as a lens. Inside it, the vision is even more deformed. Also, a piece of glowstone creates glare when the camera moves.
Showcase of camera entering water. The diffraction is changed when the camera moves around it. There is also a reflection of the water in a mirror next to it.

Noise viewer

A friend of mine asked to render 3D Perlin noise. The results are fascinating.

The value of the noise is represented by the color of the block of their transparency.

16x16x16
3D Perlin noise in a 16x16x16 hologram.
The cube has a hole where the noise is weaker,
and there are white blocks where it is stronger.
32x32x32
A mass of blocks representing Perlin noise in 3 dimensions.
Values are forming clusters depending on the type of block.
A purple mass of Perlin noise in 3 dimensions, looking like 2D Perlin noise.
64x64x64
A detailed view of Perlin noise in 3 dimensions, looking like a cave network.

Experiments

Glass are acting like a weird lens because of a faulty refraction formula.
Everything is a prism.
The glowstone slab doesn't compute and keep the previous color instead.
The light from the glowstone is not correctly stored, resulting in poor RGB rendering.

OpenCL

RGB space.
4 cubes of different colors.