A high-performance renderer to render glTF models that use the `KHR_materials_transmission` and `KHR_materials_volume` extensions.

Overview

This is a high-performance renderer designed among other things to render glTF models that use the KHR_materials_transmission and KHR_materials_volume extensions.

It can:

  • Handle rough transmissive materials such as frosted glass.
  • Approximate refracted light through transmissive models that specify a thickness.
  • Attenuate light via Beer's law.

It wasn't easy working out how to render these models. While the glTF extension READMEs as fairly extensive, I had to look through the code of the glTF-Sample-Viewer to work out implementation details.

Transmissive materials that are totally smooth and do not have a volume can be rendered without any super special tricks via pre-multiplied alpha and additive blending. Transmissive materials with any kind of roughness or volume are quite a bit trickier.

The main trick I realised from reading over the code from the glTF-Sample-Viewer is that you need to render or blit all the rendered diffuse objects to a second framebuffer texture, which you then sample in a seperate pass for all the transmissive objects. If you want to handle rough transmissive objects then you need to generate a mip-chain for this sampled texture, as rougher objects need to fetch the transmitted light of the pixels behind them in a 'blurrier' way.

In my shader code, this is done via two functions (these I did mostly copy from the gltf-Sample-Viewer). The first, ibl_volume_refraction is only ran once per pixel. It handles fetching the transmitted light from the sampled framebuffer and attenuating it.

The second, the transmission_btdf is ran once per light and handles light that is scattered through the model and out onto the other side. This only effects materials that are a bit rough.

Running

Clone https://github.com/KhronosGroup/glTF-Sample-Models into this directory as run with:

cargo run -- <gltf-sample-model-name>

transmission-renderer 0.1.0

USAGE:
    transmission-renderer [FLAGS] [OPTIONS] <gltf-sample-model-name>

FLAGS:
        --external-model    Render a model external to the glTF-Sample-Models directory, in which case the full path
                            needs to be specified
    -h, --help              Prints help information
        --log-leaks         Log allocator leaks on shutdown. Off by default because it makes panics hard to debug
    -V, --version           Prints version information

OPTIONS:
        --roughness-override <roughness-override>
            Override the default roughness factor of the model. Doesn't effect models that use a
texture for roughness

    -s, --scale <scale>                              A scale factor to be applied to the model [default: 1.0]

ARGS:
    <gltf-sample-model-name>    The name of the model inside the glTF-Sample-Models directory to
render

For some cool examples:

cargo run -- DragonAttenuation --roughness-override 0.25

cargo run -- IridescentDishWithOlives --scale 5

cargo run -- MosquitoInAmber --scale 20

cargo run -- AttenuationTest --scale 0.1

Shader Compiling

I'm using my own project, rust-gpu-cli-builder to build the shader module as I prefer this to using a build script. The arguments that I use to build it are:

--target spirv-unknown-spv1.3 --capabilities RuntimeDescriptorArray --extensions SPV_EXT_descriptor_indexing

Other Fun Stuff

Oh, it also features

  • Shader written entirely in https://github.com/EmbarkStudios/rust-gpu.
  • Basic frustum culling via a compute shader and vkCmdDrawIndexedIndirectCount.
  • A depth pre-pass setup where at max 2 full screens of fragments are processed (1 screen of opaque and 1 of transmissive objects on top).
You might also like...
Renderer-agnostic toolkit for Indie Game Developers

Indie Toolkit Renderer-agnostic toolkit for Indie Game Developers Features Not yet implemented: app_kit debug_kit input_kit asset_kit audio_kit Implem

High performance Rust ECS library
High performance Rust ECS library

Legion aims to be a feature rich high performance Entity component system (ECS) library for Rust game projects with minimal boilerplate. Getting Start

Comparing performance of Rust math libraries for common 3D game and graphics tasks

mathbench mathbench is a suite of unit tests and benchmarks comparing the output and performance of a number of different Rust linear algebra librarie

A interactive and fun to use memory game written in Rust

memg - Memory Game memg is a interactive and fun to use memory game written in rust Installation Make sure you have rust installed. Use this official

An opinionated 2D sparse grid made for use with Bevy. For storing and querying entities

bevy_sparse_grid_2d An opinionated 2D sparse grid made for use with Bevy. For storing and querying entities. Personally, I'm using it for simple stupi

A simple-to-use input manager for the Bevy game engine that empowers players and makes accessibility easy.

Bevy Ineffable A simple-to-use input manager for the Bevy game engine that empowers players and makes accessibility easy. Core tenets Make accessibili

A Bevy plugin to use Kira for game audio

Bevy Kira audio This bevy plugin is intended to try integrating Kira into Bevy. The end goal would be to replace or update bevy_audio, if Kira turns o

Easy to use game engine
Easy to use game engine

arcana Arcana is a game engine built with focus on ease of use without compromising on level of control. Getting started Starting writing a game is as

A single-threaded polling-based Rust async executor suitable for use in games, embedded systems or WASM.

simple async local executor An Enlightware® software. Overview A single-threaded polling-based executor suitable for use in games, embedded systems or

Owner
Ashley
Graphics programmer and occasional gamedev living in Berlin, DE
Ashley
A tool for creating optimised, platform specific glTF files.

Squisher What? squisher is a program that takes a glTF or .glb file with PNG/JPG textures and produces a .glb file where the textures have been replac

Let Eyes Equals Two 4 Aug 24, 2022
A low-level gltf parser implemented on nanoserde

Goth-gltf aims to be a low-level, unopinionated reader for glTF files. In comparison with gltf-rs, it: Represents the glTF JSON structure transparentl

Ashley 18 Dec 27, 2022
A plugin to use the kajiya renderer with bevy

??️ ?? bevy-kajiya A plugin that enables use of the kajiya renderer in bevy WARNING: This plugin is barebones and supports a limited set of features.

Sebastian Hamel 79 Jan 5, 2023
realize XPBD with rust and render in Unity

XPBD Simulation with Rust & Unity 上次看了XPBD的论文,最近又恰好在学习Rust,于是就想着用Rust来实现一个XPBD Solver练一下手,正好一箭双雕。 XPBD结论公式可参考此篇 - XPBD论文解读(Extended Position-Based Dyn

zilch 23 Nov 15, 2022
Bevy engine + miniquad render plugin

Bevy engine + miniquad renderer This is a plugin for Bevy engine that replaces default windowing and rendering plugins with miniquad based one. Usage

Tomasz Sterna 31 Dec 9, 2022
Pixel-Perfect, 2D Renderer for Bevy that Seamlessly Targets Desktop and Web

bevy_retro ( Screenshot of Bounty Bros. game made with Bevy Retro and Skip'n Go ) Bevy Retro is a 2D, pixel-perfect renderer for Bevy that can target

Katharos Technology 224 Dec 23, 2022
Text Renderer written in Rust using HarfBuzz for shaping, FreeType for rasterization and OpenGL for rendering.

Provok Text Renderer written in Rust using HarfBuzz for shaping, FreeType for rasterization and OpenGL for rendering. Input Provok is fed with a JSON

Ossama Hjaji 67 Dec 10, 2022
Rust-based replacement for the default Minecraft renderer

wgpu-mc ?? A blazing fast alternative renderer for Minecraft Intro WebGPU is a new web specification designed to provide modern graphics and compute c

Birb 1 Jun 28, 2022
Sdf 2d shape renderer for Bevy

bevy_smud Sdf 2d shape rendering for Bevy. Bevy smud is a way to conveniently construct and render sdf shapes with Bevy. Given a shape function/expres

Johan Klokkhammer Helsing 85 Jan 2, 2023
🦅🦁 Fast, simple 2D text renderer for wgpu

?? glyphon ?? Fast, simple 2D text rendering for wgpu What is this? This crate provides a simple way to render 2D text with wgpu by: rasterizing glyph

Josh Groves 60 Nov 5, 2022