Skip to content

li23179/renderer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

57 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

C++ Standard CMake

C++ Software Renderer

Renderer Banner

A lightweight 3D graphics renderer written in C++, built from scratch without relying on modern GPU APIs such as OpenGL or DirectX.

This project demonstrates the core concepts of a rasterisation pipeline — including transformation matrices, barycentric interpolation, depth buffering, and texture mapping — implemented on the CPU.


Features Overview

Rasterisation Pipeline

  • Model -> World -> View -> Projection transforms
  • Perspective-correct barycentric interpolation
  • Depth buffer (Z-buffer)
  • Texture mapping

Ray Tracing Engine

  • Recursive Ray Tracing
  • Hard & Soft shadows
  • Mirror Reflection
  • Metallic Surface (Perturbated Reflection)
  • Glass / Water Refraction (Fresnel reflectance with Schlick approximation)
  • Environment Map Sampling when no intersection

Photon Mapping (Global + Caustics)

  • Two-pass algorithm (Photon Emission & Storage -> Estimate Irradiance)
  • Cosine-weighted hemisphere sampling for Photon Direction
  • Caustic photon map for refractive caustics
  • 3D KD-tree + K-Nearest Neighbour for queries
  • Russian roulette termination depend on the material

Camera System

  • Free-flight movement
  • Yaw / pitch rotation (Q/E + Z/C)
  • Orbit modes about X and Y (O, X)
  • Depth of field & bokeh via aperture sampling
  • Adjustable focus distance and aperture size

Lighting

  • Spherical Point Source sampling with Uniform Distribution (Soft Shadow)
  • Light Circular Motion (Orbit Light)

Environment Mapping

  • Toggle background/environment reflections (N key)
  • Uses Spherical Map for Environment Mapping

Animation & Recording

  • Frame-by-frame PPM output
  • Automatic folder clearing & naming
  • ffmpeg pipeline for MP4 export
  • Light orbit & camera orbit animation presets

Material

  • Type: Opaque, Mirror, Metallic, Glass
  • Reflectivity
  • Tint
  • Roughness
  • Transparency
  • Refractive Index

Controls

Camera Movement

Key Action
↑ / ↓ / ← / → Move up / down / left / right
W / S Move forward / backward

Camera Rotation

Key Action
Q / E Pan left / right
Z / C Tilt up / down

Lens Movement

Key Action
I Increase focus distance
U Decrease focus distance
M Increase aperture radius (stronger bokeh)
, Decrease aperture radius (weaker bokeh)

Light Movement

Key Action
H / L Move light left / right
K / J Move light up / down
G / ; Move light forward / backward
P Toggle light orbit

Animation

Key Action
O Toggle camera orbit about Y-axis
X Toggle camera orbit about X-axis
F Fly-through animation
T Demonstration Sequence
B Bokeh depth-of-field effect

Raytracer Rendering Toggles

Key Action
N Enable / disable environment map

Reset to Initial Configuration

Key Action
R Reset to Initial Camera and Light Position

Photon Mapping

To enable Photon mapping, you need to alter the renderer.usePhotonMap flag in Renderer.cpp file


Testing Materials (OBJ & MTL)

Some materials such as gold, mirror, and glass have very low diffuse values, so they are difficult to see without an environment map.
Press N to enable the environment map when testing these materials.

You can switch between materials by editing the usemtl tag inside the corresponding OBJ file:

usemtl gold_ball
usemtl mirror_ball
usemtl glass_ball

Build Instructions

Using Makefile

git clone git@github.com:<your_github_id>/Renderer.git
cd Renderer
make clean
make speedy      # fast build (optimised) but buggy

Recording & Animation Export

The renderer supports per-frame recording for animations, camera orbits, fly-throughs, and bokeh demonstrations.

1. Enable Recording

Firstly, set the desired title / feature / material you want to record, by changin the line

const std::string title = "<your_title>";

Recording is triggered automatically in the rendering loop, if you want to enable recording undo these comment

clearDirectory(title, window);
size_t ppm_frame = 0;

record(ppm_frame, title, window);
ppm_frame++;

If the folder already exists, it is cleared before a new recording begins.

If you want to end the recording, press ESC to stop the recording and exit the renderer.

2. Converting Frames to MP4

Use ffmpeg to convert the PPM sequence into a video:

ffmpeg -framerate 30 -i frames/<your_title>/frame%04d.ppm -c:v libx264 -pix_fmt yuv420p <your_output>.mp4

Now you will get a fresh recording of your desired features / material demonstration !!


© 2025 Gordon Wai Hin Kam. All rights reserved.

About

C++ graphic engine

Resources

Stars

Watchers

Forks

Contributors

Languages