{"id":50308245,"url":"https://github.com/expenses/transmission-renderer","last_synced_at":"2026-05-28T18:01:57.707Z","repository":{"id":45384666,"uuid":"431131881","full_name":"expenses/transmission-renderer","owner":"expenses","description":"A high-performance renderer to render glTF models that use the `KHR_materials_transmission` and `KHR_materials_volume` extensions.","archived":false,"fork":false,"pushed_at":"2022-01-25T17:11:18.000Z","size":6059,"stargazers_count":35,"open_issues_count":2,"forks_count":0,"subscribers_count":4,"default_branch":"dodgy-tracy-support","last_synced_at":"2024-04-15T23:14:06.410Z","etag":null,"topics":["gltf","gltf2","rust","rust-lang","vulkan","vulkan-api"],"latest_commit_sha":null,"homepage":"","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/expenses.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-11-23T14:27:42.000Z","updated_at":"2024-02-15T09:35:07.000Z","dependencies_parsed_at":"2022-09-18T22:23:10.744Z","dependency_job_id":null,"html_url":"https://github.com/expenses/transmission-renderer","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/expenses/transmission-renderer","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expenses%2Ftransmission-renderer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expenses%2Ftransmission-renderer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expenses%2Ftransmission-renderer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expenses%2Ftransmission-renderer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/expenses","download_url":"https://codeload.github.com/expenses/transmission-renderer/tar.gz/refs/heads/dodgy-tracy-support","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/expenses%2Ftransmission-renderer/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33619972,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-05-28T02:00:06.440Z","response_time":99,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gltf","gltf2","rust","rust-lang","vulkan","vulkan-api"],"created_at":"2026-05-28T18:01:57.424Z","updated_at":"2026-05-28T18:01:57.699Z","avatar_url":"https://github.com/expenses.png","language":"Rust","funding_links":[],"categories":[],"sub_categories":[],"readme":"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.\n\n![](readme/examples.png)\n\nIt can:\n\n* Handle rough transmissive materials such as frosted glass.\n* Approximate refracted light through transmissive models that specify a thickness.\n* Attenuate light via Beer's law.\n\nIt wasn't easy working out how to render these models. While the [glTF extension READMEs](https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_materials_transmission) as fairly extensive, I had to look through the code of the [glTF-Sample-Viewer] to work out implementation details.\n\nTransmissive 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](https://stackoverflow.com/a/67047837/15390861). Transmissive materials with any kind of roughness or volume are quite a bit trickier.\n\nThe 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.\n\nIn my shader code, this is done via two functions (these I did mostly copy from the [gltf-Sample-Viewer]). The first, [`ibl_volume_refraction`](https://github.com/expenses/transmission-renderer/blob/0b06623e8c4e67b1cd44256cc050097dbfa169ab/glam-pbr/src/lib.rs#L290-L348) is only ran once per pixel. It handles fetching the transmitted light from the sampled framebuffer and attenuating it.\n\nThe second, the [`transmission_btdf`](https://github.com/expenses/transmission-renderer/blob/0b06623e8c4e67b1cd44256cc050097dbfa169ab/glam-pbr/src/lib.rs#L195-L231) 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.\n\n## Running\n\nClone https://github.com/KhronosGroup/glTF-Sample-Models into this directory as run with:\n\n`cargo run -- \u003cgltf-sample-model-name\u003e`\n\n```\ntransmission-renderer 0.1.0\n\nUSAGE:\n    transmission-renderer [FLAGS] [OPTIONS] \u003cgltf-sample-model-name\u003e\n\nFLAGS:\n        --external-model    Render a model external to the glTF-Sample-Models directory, in which case the full path\n                            needs to be specified\n    -h, --help              Prints help information\n        --log-leaks         Log allocator leaks on shutdown. Off by default because it makes panics hard to debug\n    -V, --version           Prints version information\n\nOPTIONS:\n        --roughness-override \u003croughness-override\u003e\n            Override the default roughness factor of the model. Doesn't effect models that use a\ntexture for roughness\n\n    -s, --scale \u003cscale\u003e                              A scale factor to be applied to the model [default: 1.0]\n\nARGS:\n    \u003cgltf-sample-model-name\u003e    The name of the model inside the glTF-Sample-Models directory to\nrender\n```\n\nFor some cool examples:\n\n`cargo run -- DragonAttenuation --roughness-override 0.25`\n\n`cargo run -- IridescentDishWithOlives --scale 5`\n\n`cargo run -- MosquitoInAmber --scale 20`\n\n`cargo run -- AttenuationTest --scale 0.1`\n\n## Shader Compiling\n\nI'm using my own project, [rust-gpu-cli-builder](https://github.com/expenses/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:\n\n`--target spirv-unknown-spv1.3 --capabilities RuntimeDescriptorArray --extensions SPV_EXT_descriptor_indexing`\n\n## Other Fun Stuff\n\nOh, it also features\n\n* Shader written entirely in [https://github.com/EmbarkStudios/rust-gpu](rust-gpu).\n* Basic frustum culling via a compute shader and `vkCmdDrawIndexedIndirectCount`.\n* 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).\n\n[glTF-Sample-Viewer]: https://github.com/KhronosGroup/glTF-Sample-Viewer\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexpenses%2Ftransmission-renderer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fexpenses%2Ftransmission-renderer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fexpenses%2Ftransmission-renderer/lists"}