Skip to content

Latest commit

 

History

History

path_tracer

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

path_tracer

This is an implementation of a spectral path tracer that makes use of Vulkan ray tracing extensions via caldera.

Features

  • A uni-directional spectral path tracer
    • Currently samples 3 wavelengths per ray
    • Implemented as a single Vulkan ray tracing pipeline
    • Support for instanced geometry (via instanced bottom-level acceleration structures)
  • Sampling using either pmj02 or sobol sequences (see links below)
  • BSDF importance sampling
    • Diffuse and mirror "ideal" surfaces
    • Smooth or rough fresnel dieletrics and conductors
    • Diffuse with dielectric coating
  • Importance sampling of lights
    • Quad/disc/sphere or triangle mesh shaped emitters
    • Dome or solid angle distant lights
  • Multiple importance sampling between BSDFs and lights
  • Simple fixed material model
    • Reflectance from per-instance constant and/or texture
    • All other parameters are either per-instance or global constants (for now)
  • Interactive renderer with moveable camera and debug UI

The implementation makes use of the following Vulkan extensions:

  • VK_KHR_ray_tracing_pipeline and VK_KHR_acceleration_structure for tracing of rays. For now rays are traced using a single pipeline with all shading/sampling/traversal for a full path with multiple bounces.
    • The pipeline contains several different intersection and hit shaders to handle ray tracing against analytic shapes such as spheres and discs in addition to triangle meshes.
  • VK_KHR_buffer_device_address to reference a GPU buffer using a uint64_t device address. This extension is required by VK_KHR_ray_tracing_pipeline for the shader binding table and vastly simplifies the setup of buffers, avoiding a lot of descriptor management code. The device address can be cast to a buffer reference of any type, so this can be useful to implement more generic GPU data structures.
  • VK_EXT_descriptor_indexing for "bindless" texturing. This extension is also required by VK_KHR_ray_tracing_pipeline and allows us to bundle all textures into a single descriptor set with an array per texture type, and refer to them by index when they need to be sampled. Since different GPU threads can require different texture indices during ray tracing, we additionally make use of "non-uniform indexing" in the shader code.

Links

Here are some of the references used when creating the renderer:

The following crates have been super useful in making the app:

  • ultraviolet: maths library with nice API, used for vectors and transforms
  • bytemuck: safely alias data as bytes, used for copying to GPU buffers
  • imgui/imgui-winit-support: rust API for the fantastic Dear ImGui, for debug UI
  • serde/serde_json: amazing lib to generate serialisation for rust data structures, used to load Tungsten format JSON scenes
  • stb: rust API for the stb libraries, used for image IO and BC compression
  • winit: cross platform windowing and events

How To Run

The code can be run as follows (will show a Cornell box by default):

make && cargo run --release --example path_tracer --

By default this will create a window with a progressive renderer and debug UI for many parameters. Additionally you can drag with the mouse and use W/A/S/D on the keyboard to move the camera. For command-line help run as:

make && cargo run --release --example path_tracer -- help

Several of the images below are loaded from Tungsten format scenes. These can be loaded into the renderer by running using the commandline:

make && cargo run --release --example path_tracer -- tungsten <scene_json_file_name>

Test Images

As is tradition, here are some boxes under a couple of different lighting conditions (original Cornell box data, and a variant with a mirror material and distant lights).

cornell-box cornell-box_dome-light

Here is a variation on the classic Veach multiple importance sampling scene, showing 64 samples per pixel with BSDF sampling only, 64 with light sampling only, then 32 samples of each weighted using multiple importance sampling. These images demonstrate how multiple importance sampling effectively combines BSDF and light sampling to reduce variance over the whole image.

BSDF Sampling Only Light Sampling Only Combine with MIS
cornell-box_conductor_surfaces-only cornell-box_conductor_lights-only cornell-box_conductor

Here is a test scene for some conductors using spectral reflectance data from refractiveindex.info for copper, iron and gold under a uniform illuminant (the colours are entirely from the reflectance data, there is no additional tinting).

trace_material_conductors

If we change the illuminant to F10 (which has a very spiky distribution), we can check the effect that wavelength importance sampling has on colour noise. The following images use gold lit with F10, all with 8 paths per pixel and 3 wavelengths per path. The first image samples wavelengths uniformly, the second samples only the hero wavelength for that path proportional to F10, the third image samples all wavelengths for that path proportional to F10 (reproducing part of the result of Continuous Multiple Importance Sampling):

Uniform Sampling Sample Hero Wavelength Only Sample All Wavelengths
trace_material_gold_f10_uniform trace_material_gold_f10_hero trace_material_gold_f10_continuous

Gallery

The next set of images are rendered from these excellent rendering resources by Benedikt Bitterli and blendswap.com artists nacimus, Wig42, cekuhnen, Jay-Artist, thecali, NewSee2l035 and aXel.

bathroom2

staircase coffee

living-room-2

spaceship

staircase2

glass-of-water

There is a barely started exporter for Blender, but support for materials beyond a simple texture map is a bit out of scope for now. This image uses the "Classroom" Blender demo file, with highly approximated materials and only sunlight:

blender

Potential Future Work

  • Denoiser?
  • Adaptive sampling
  • HDR display output
  • Rough dielectrics
  • Smooth conductors
  • Generic clearcoat?
  • IOR parameters for conductors
  • IOR parameters for dielectrics
  • Interior media
  • Sobol sampler
  • Thin lens camera
  • Volumetrics
  • Image-based dome light
  • More flexible materials (graphs?)
  • Disc primitive
  • Triangle mesh emitter?
  • Microfacet multi-scattering?
  • Path re-use?
  • Spectral rendering?
  • Spiky illuminants (F10)