• Stars
    star
    119
  • Rank 297,930 (Top 6 %)
  • Language
    C++
  • Created over 5 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Toy Mesh Path Tracer that I used as a base for job interview tasks

Toy Mesh Path Tracer for a job interview task

I used the task below for some job interviews I did in 2019 Q2. The initial version was a super simple brute-force triangle mesh path tracer (no acceleration structures, no threading, etc.), and the task was to make it faster. Of course I wanted to know how much faster it can get, so I did some simple speedups myself in parallel.

The original non-optimized-at-all version is at 01-initial-job-task tag. I made other tags for later snapshots; here they are with performance numbers (measured on 2018 MacBookPro i9), on the teapot.obj (15706 triangles) and sponza.obj (66452 triangles) scenes respectively:

  • 01-initial-job-task, initial: 3.5 and LOLNOPE Krays/s
  • 02-multi-threaded, multi-threading: 18.9 and LOLNOPE Krays/s
  • 03-bvh, simple bounding volume hierarchy: 6978.2 and 1350.3 Krays/s
  • 04-simd, simplistic naïve SIMD: 8919.0 and 1853.1 Krays/s
  • 05-change-ray-tri-algo, better ray-triangle intersection test: 10251.1 and 1952.5 Krays/s
  • 06-shadow-rays, faster code path for shadow rays: 10888.0 and 2568.3 Krays/s
  • 07-compare-with-embree, compare with Intel Embree 3.5.2: 75965.0 and 40800.8 Krays/s (yup, Embree is fast!)
  • 08-compare-with-nanort, compare with NanoRT: 20638.2 and 4197.9 Krays/s

And yeah, I know -- most obvious next steps would be to use better BVH building heuristics (like SAH), and doing SIMD properly instead of "let's make our vector/ray/color class use SIMD". I did not get to that (yet?), but in any case -- the code is already over 3000 times faster than the initial version. With the BVH being the major win, as one would expect.

Original desceription of the interview task is below:

Interview task/assignment: speed up a simple path tracer

This project contains a simple triangle mesh path tracer implemented in C++. It's a command line application that takes screen size & input .OBJ data file parameters, renders it using "path tracing" algorithm and produces output.png result file.

Here are some images that the program can produce with the data files present under data/ directory:

result1 result2

The Task

Current program is slow. Really slow. Rendering that monkey head model ("Suzanne") at a lowly 640x360 resolution, 4 samples per pixel, takes one minute on my PC! Rendering the other image ("Sponza") at the same resolution takes five hours.

Your task then is, of course, to make the program faster :)

I know for sure that it is possible to make it faster by more than a hundred times -- e.g. I got Suzanne from a minute down to 0.2 seconds, and Sponza from five hours down to 8 seconds. It might be possible to make it even faster, but I did not quite go there.

Now, your task is to make it run as fast as you can. I'm not asking for a "hundred times", but something like "at least ten times faster" is what you should aim for.

It's entirely your choice how you will do it. Better algorithms? More efficient math? Better data layout? Multi-threading? SIMD? Rewrite in assembly? Rewrite as a compute shader / CUDA / OpenCL? Rewrite for NVIDIA RTX? All of these? You pick :) Some of what I listed here is "certainly overkill" and not needed; achieving a 10x faster performance is entirely possible using relatively simple means.

Go!

What I will be looking at

  • Overall I would recommend making a clone of this project on github and using "actual version control" workflow to make your changes. If you don't like git or version control, that's fine; I can accept submissions in zip or dropbox or google drive (or whatever) form. As long as I can see the code and try it out.
  • Your optimized program should produce same looking images as the original one, just do it faster.
  • I'll be looking at "everything" that is important in programming job: whether the code works correctly, is understandable, how is it structured, how it behaves performance wise (computing usage, memory usage etc.).
  • It is very likely that your first submission will not be quite good, so do not delay it until the last day! Usually it takes 2-4 iterations to arrive at a good solution.

About the code

I made it work on Windows (Visual Studio 2017) and Mac (Xcode 10); the project files for them are respectively in projects/VisualStudio/TrimeshTracer.sln and projects/Xcode/TrimeshTracer.xcodeproj. In Visual Studio project, you might need to update settings to whatever Windows SDK version you have, I picked the oldest I had on my machine. If you have any trouble building or running it, ask me!

The application accepts four command line arguments as input: <width> <height> <spp> <datafile>:

  • width is image width in pixels,
  • height is image height in pixels,
  • spp is "samples per pixel"; kind of like "anti-aliasing level",
  • datafile is path to a mesh to render; in Wavefront .OBJ format.

I added some example meshes under data/ folder; initially I suggest starting with e.g. data/cube.obj which is just a simple cube. I do not recommend trying to run the non-optimized version of the program on for example the Sponza model - it contains 66k triangles and will run very very slow.

The code itself is fairly simple C++ code, and I tried to comment it extensively. No previous experience with ray-tracers or path-tracers should be required.

If you do want to read up on what this "path tracing" thing is (and maybe even get some ideas how to make it faster? who knows), I can recommend "Ray Tracing in a Weekend", "Ray Tracing: The Next Week" and "Ray Tracing: the Rest of Your Life" minibook series, which have been recently made free here. The internet is full of other information about ray/path tracing as well.

For reference, here are the performance numbers I get on my laptop (2019 MacBookPro i9 2.9GHz), rendering at 640x360, 4 samples per pixel, on this un-optimized implementation:

  • cube.obj (14 triangles): 3818.3 KRay/s (0.6 sec)
  • suzanne.obj (970 triangles): 48.3 KRays/s (53.0 sec)
  • teapot.obj (15706 triangles): 3.5 KRays/s (683.0 sec)
  • sponza.obj (66452 triangles): LOL nope, ain't nobody got time for that

More Repositories

1

UnityGaussianSplatting

Toy Gaussian Splatting visualization in Unity
C#
2,025
star
2

glsl-optimizer

GLSL optimizer based on Mesa's GLSL compiler. Used to be used in Unity for mobile shader optimization.
C++
1,729
star
3

ToyPathTracer

Toy path tracer for my own learning purposes (CPU/GPU, C++/C#, Win/Mac/Wasm, DX11/Metal, also Unity)
C++
1,058
star
4

ClangBuildAnalyzer

Clang build analysis tool using -ftime-trace
C++
979
star
5

hlsl2glslfork

HLSL to GLSL language translator based on ATI's HLSL2GLSL. Used in Unity.
C++
558
star
6

dod-playground

Sample OOP/ECS/DOD project (C++) for an internal Unity lecture in 2018
C++
366
star
7

smol-v

SMOL-V: like Vulkan/Khronos SPIR-V, but smaller.
C++
296
star
8

sizer

Win32/64 executable size reporting
C++
252
star
9

UnityGPUTexCompression

How to do DXT/BCn texture compression in Unity using compute shaders
C#
66
star
10

gamedev-emojis

128x128 sized icons of various game development things
Python
60
star
11

miniexr

Small code to write OpenEXR images
C++
58
star
12

demo-pd-cranktheworld

A real-time rendering demo for Playdate console
C
56
star
13

smol-atlas

2D rectangular bin packing with option for item removal
C++
53
star
14

UnityStbEasyFont

C#
47
star
15

HashFunctionsTest

Little test of various hash functions
C++
46
star
16

header_hero

Fork of Bitsquid's Header Hero tool
C#
41
star
17

BlackHoleDemo

C#
27
star
18

smol-compute

A tiny library for launching compute shaders on D3D11, Metal and Vulkan
C
26
star
19

markdeep-docs-style

Documentation CSS style for Markdeep
CSS
25
star
20

dingus

engine used in some nesnausk! demos
C++
23
star
21

glsl-load-speed

Quick test of GLSL shader loading speed
C++
17
star
22

obj_parse_tester

Comparing various C++ OBJ parsing libraries
C
17
star
23

bcn_decoder_tester

Testing various BCn texture format decoding libraries
C++
16
star
24

jobtask2019-trimesh-tracer

A programming task for job interviews I did in 2019 Q2
C++
16
star
25

bc7e-on-gpu

An attempt to port BC7E texture compressor to a GPU compute shader
HLSL
15
star
26

float_compr_tester

Testing various libraries/approaches for compressing floating point data
HTML
14
star
27

aras-p.hugo

This is just my website, content & Hugo bits
HTML
9
star
28

oklab_gradient_test

C++
6
star
29

sprint-fuuu

C++
6
star
30

sideshooter50

A game in 50 lines of code
4
star
31

twod_coverage_raster

Super simplistic 2D triangle coverage rasterizer
C
4
star
32

SoftRenderBlogProject

C
3
star
33

trianglomator

C#
3
star
34

dod-lecture-2018

C#
3
star
35

ggj19-rumba

A small game during Global Game Jam 2019
C#
3
star
36

filteression

C++
2
star
37

hgext

misc hg extension stuff
Python
1
star
38

website

PHP
1
star
39

image-formats-testbed-hack

C++
1
star