Its general goal is to get as close as possible to path-traced reference at real-time rates in dynamic scenes, without any precomputed light transport, or manually placed light probes.
kajiya does not currently aim to be a fully-featured renderer used to ship games, support all sorts of scenes, lighting phenomena, or a wide range of hardware. It's a hobby project, takes a lot of shortcuts, and is perpetually a work in progress.
Ruins environment rendered in kajiya. Scene by Crebotoly
- Hybrid rendering using a mixture of raster, compute, and ray-tracing
- Dynamic global illumination
- Multi-bounce temporally-recurrent voxel-based diffuse
- Short-range ray-traced diffuse for high-frequency details
- Single bounce specular, falling back to diffuse after the first hit
- Sun with ray-traced soft shadows
- Standard PBR with GGX and roughness/metalness
- Energy-preserving multi-scattering BRDF
- Reference path-tracing mode
- Temporal super-resolution and anti-aliasing
- Natural tone mapping
- Physically-based glare
- Basic motion blur
- Contrast-adaptive sharpening
- Optional DLSS support
- GLTF mesh loading (no animations yet)
- A render graph running it all
- A quick presentation about the renderer
- Repository highlights:
- Notable branches:
restir-meets-surfel- latest experimental branch, with new GI in the works
kajiya currently works on a limited range of operating systems and hardware.
- Nvidia RTX series
- Nvidia GTX 1060 and newer with 6+ GB of VRAM (slow: driver-emulated ray-tracing)
- AMD Radeon RX 6000 series
(Some) Linux dependencies
- In case the bundled
libdxcompiler.sodoesn't work: https://github.com/microsoft/DirectXShaderCompiler#downloads
(Some) MacOS dependencies
brew install ossp-uuid)
Building and running
kajiya and its tools, you need Rust.
There's a very minimal asset pipeline in
bake.rs, which converts meshes from GLTF to an internal flat format, and calculates texture mips. In order to bake all the provided meshes, run:
When done, run the renderer demo (
view app from
[scene_name] is one of the file names in
assets/scenes, without the
.ron extension, e.g.:
cargo run --bin view --release -- --scene battle --width 1920 --height 1080 --no-debug
Controls in the
- WSAD, QE - movement
- Mouse + RMB - rotate the camera
- Mouse + LMB - rotate the sun
- Shift - move faster
- Ctrl - move slower
- Space - switch to reference path tracing
- Backspace - reset view to previous saved state
- Tab - show/hide the UI
view app, DPI scaling in the operating system affects the physical number of pixels of the rendering output. The
--height parameters correspond to logical window size and the internal rendering resolution. Suppose the OS uses DPI scaling of
1.5, and the app is launched with
--width 1000, the actual physical width of the window will be
1500 px. Rendering will still happen at
1000 px, with upscaling to
1500 px at the very end, via a Catmull-Rom kernel.
kajiya can also render at a reduced internal resolution, and reconstruct a larger image via temporal upsampling, trading quality for performance. A custom temporal super-resolution algorithm is used by default, and DLSS is supported on some platforms. Both approaches result in better quality than what could be achieved by simply spatially scaling up the image at the end.
--width 1920 --height 1080 --temporal-upsampling 1.5 will produce a
1920x1080 image by upsampling by a factor of
1280x720. Most of the rendering will then happen with
1.5 * 1.5 = 2.25 times fewer pixels, resulting in an almost 2x speedup.
Adding Meshes and Scenes
To add new mesh(es), open
bake.cmd (Win) /
bake.sh (Linux), and add
- cargo run --bin bake --release -- --scene "[path]" --scale 1.0 -o [mesh_name]
To add new scenes, in
\assets\scenes, create a
[scene_name].ron with the following content:
( instances: [ ( position: (0, 0, 0), mesh: "[mesh_name]", ), ] )
- Vulkan API usage is extremely basic. Resources are usually not released, and barriers aren't optimal.
- There are hard limit on mesh data and instance counts. Exceeding those limits will result in panics and Vulkan validation errors / driver crashes.
- Window (framebuffer) resizing is not yet implemented.
- The voxel GI uses a fixed-size volume around the origin by default.
--gi-volume-scaleto change its extent in the
- It can be configured to use camera-centered cascades at an extra performance cost (see
- Denoising needs more work (always).
This project is made possible by the awesome open source Rust community, and benefits from a multitude of crates
Special shout-outs go to:
- Felix Westin for his MinimalAtmosphere, which this project uses for sky rendering
- AMD, especially Dominik Baumeister and Guillaume Boissé for the FidelityFX Shadow Denoiser, which forms the basis of shadow denoising in
- Maik Klein for the Vulkan wrapper ash, making it easy for
kajiyato talk to the GPU.
- Traverse Research and Jasper Bekkers for a number of highly relevant crates:
We welcome community contributions to this project.
Any contribution intentionally submitted for inclusion in an Embark Studios project, shall comply with the Rust standard licensing model (MIT OR Apache 2.0) and therefore be dual licensed as described below, without any additional terms or conditions:
This contribution is dual licensed under EITHER OF
- Apache License, Version 2.0, (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
For clarity, "your" refers to Embark or any other licensee/user of the contribution.