- Simple demonstration of path tracing a.k.a. ray tracing.
- Ray intersection with fractal geometry is calculated by ray marching distance estimated fields.
- Cross-platform GPU support with web-gpu. (Intel's GPU on Windows is broken, sorry!)
Either download the pre-built binary or build it yourself.
Pre-built binary: The program can be downloaded from releases.
Building from source:
Install rust and run:
cargo run --release
. On Windows systems you need to also install Visual Studio C++ tools.
| Key | Action |
|---|---|
W, A, S, D, Space Left Shift |
Move camera |
Arrow keys |
Change the camera direction |
Q, E |
Change the focal distance of the camera |
Z, C |
Change the aperture of the camera |
Right Shift |
Fine tuning: All movements are reduced to 20% of the original |
P |
Print image as PNG |
R |
Reset all parameters to initial state |
(V, F), (B, G), (N, J), (M, K) |
Debugging: tune fractal colors. |
This project has nearly identical CPU-implementation, which is more clear in illustrating the function of a path tracer.
https://gitlab.com/tolvanea/simple_path_tracer_cpu
The CPU-implementation does not contain any GPU boilerplate code, making it quite compact with about 230 lines of code. Note that this GPU implementation has over 1000 lines of boilerplate code. Also this GPU implementation utilizes some branch-optimization making the path tracing code a bit less obvious. However, remember that high-quality CPU rendering takes hours, as CPU:s are 10-100 times slower than GPU:s.
Overview of the file structure is:
main.rsHigh-level GPU logic and camera controls.wgpu_boilerplate.rsNitty-gritty details for initializing GPU shaders and buffers.window_boilerplate.rsWindow event loop that schedules every frame draw.compute.wgslCompute shader that does the path tracing. It cumulates image into a texture.render.wgslRender shader that only just draws that texture to screen.
So, compute.wgsl contains all path-tracer related stuff, and the rest is boring boilerplate required to get something drawn on screen. The main beef is in shader compute.wgsl, which basically takes input of a pixel coordinate and outputs the color for that pixel.
I am grateful for iquilez for all his great blog posts and code samples. Also, 1, 2, 3 and 4 have been a great resources.
All your GPUs are listed at the start of the program. If the default GPU is not what you want, you can change it. There are two ways to do that:
Using select command line argument
You can pass command line argument select, which gives interactive list to select GPU from. The list may also contain different back ends (e.g. Vulkan, DirectX12), and CPU-emulation (e.g. llvmpipe). If you have complied the the code, run cargo run --release select or if you have downloaded the binary, run (on linux) ./simple_path_tracer select
Using environment variable
The GPU can also be selected with by running the command with an WGPU_ADAPTER_NAME environment variable. In Linux/bash it is done with
WGPU_ADAPTER_NAME=XXXX cargo run --release
where XXXX is any substring of the GPU's name. For example, substring 1080 will match NVIDIA GeForce 1080ti.
-
The program may crash with Intel integrated GPU drivers due to the "parent device is lost" -error. This is a driver issue, and out of my reach. Scaling the window smaller may solve the problem.
-
The program does not yet run on web-browsers, even though web-gpu should make it possible. So only the native binary works for now. I'm waiting
wgpu-rslibrary to mature out on that matter.
Do the whatever you want.
