bevy
bevy copied to clipboard
Implement clearcoat per the Filament and the `KHR_materials_clearcoat` specifications.
Clearcoat is a separate material layer that represents a thin translucent layer of a material. Examples include (from the Filament spec) car paint, soda cans, and lacquered wood. This commit implements support for clearcoat following the Filament and Khronos specifications, marking the beginnings of support for multiple PBR layers in Bevy.
The KHR_materials_clearcoat
specification describes the clearcoat support in glTF. In Blender, applying a clearcoat to the Principled BSDF node causes the clearcoat settings to be exported via this extension. As of this commit, Bevy parses and reads the extension data when present in glTF. Note that the gltf
crate has no support for KHR_materials_clearcoat
; this patch therefore implements the JSON semantics manually.
Clearcoat is integrated with StandardMaterial
, but the code is behind a series of #ifdef
s that only activate when clearcoat is present. Additionally, the pbr_feature_layer_material_textures
Cargo feature must be active in order to enable support for clearcoat factor maps, clearcoat roughness maps, and clearcoat normal maps. This approach mirrors the same pattern used by the existing transmission feature and exists to avoid running out of texture bindings on platforms like WebGL and WebGPU. Note that constant clearcoat factors and roughness values are supported in the browser; only the relatively-less-common maps are disabled on those platforms.
This patch refactors the lighting code in StandardMaterial
significantly in order to better support multiple layers in a natural way. That code was due for a refactor in any case, so this is a nice improvement.
A new demo, clearcoat
, has been added. It's based on the corresponding three.js demo, but all the assets (aside from the skybox and environment map) are my original work.
Changelog
Added
-
StandardMaterial
now supports a clearcoat layer, which represents a thin translucent layer over an underlying material. - The glTF loader now supports the
KHR_materials_clearcoat
extension, representing materials with clearcoat layers.
Migration Guide
-
The lighting functions in the
pbr_lighting
WGSL module now have clearcoat parameters, ifSTANDARD_MATERIAL_CLEARCOAT
is defined. -
The
R
reflection vector parameter has been removed from some lighting functions, as it was unused.
The generated examples/README.md
is out of sync with the example metadata in Cargo.toml
or the example readme template. Please run cargo run -p build-templated-pages -- update examples
to update it, and commit the file change.
You added a new feature but didn't update the readme. Please run cargo run -p build-templated-pages -- update features
to update it, and commit the file change.
@robtfm How would you like me to improve the example? I wanted to include a transparent one because @JMS55 asked me how clearcoat looked with transparency. Should I add more of a noise pattern to the car paint? Redo the golf ball texture?
@robtfm I tried to improve the lighting code as I went and make it as easy to follow as possible. Sorry to hear that I didn't succeed :( Do you have any suggestions?
@robtfm How would you like me to improve the example? I wanted to include a transparent one because @JMS55 asked me how clearcoat looked with transparency. Should I add more of a noise pattern to the car paint? Redo the golf ball texture?
i think the main issue i have is the specular aliasing from the normal maps. it seems less "bitty" in the 3js version. perhaps just downres the normal map, or just use a smaller one maybe so the single pixel highlights are less frequent? the texture on the carpaint is nicer in 3js as well (and the spinning spheres) but i'm not sure that's worth adding a new texture for.
@robtfm I tried to improve the lighting code as I went and make it as easy to follow as possible. Sorry to hear that I didn't succeed :( Do you have any suggestions?
yes sorry, i didn't mean to sound so critical. i think if you hadn't made such an effort it would be much worse, whereas now it's not much worse, and with more functionality. the 2 specific comments about a param struct and factoring the meshlet sample were the main things i thought would help. i guess if the lighting functions api is clean then at least the trickier stuff is more contained.
@robtfm I believe every comment has been addressed. pbr_lighting.wgsl
has been largely rewritten. I made the spheres rotate, added some blur and decreased the levels on the scratch normal map, added some subtle blue noise as a normal map to the car paint, and switched to ACES filmic tonemapping, as this is what makes the normal map on the car paint in three.js appear purple.
just a first pass. the changes to the core lighting functions are pretty extensive, @mockersf could we please run a demo comparison?
Mostly good, just a change in the transmission example: https://pixel-eagle.vleue.com/project/B25A040A-A980-4602-B90C-D480AB84076D/run/852/compare/840?screenshot=3D%20Rendering/transmission.png
How do I get rid of the GitHub typos check on Fo
?
add it to https://github.com/bevyengine/bevy/blob/main/typos.toml
I think I fixed the transmission example, but it's hard for me to check locally as it's animated.
the gold and golf balls looks great now, but the blue sphere doesn't show: ERROR bevy_asset::server: Path not found: [...]/assets/textures/BlueNoise-Normal.png
@robtfm Oops, forgot to check that file in! Fixed.
I’ve read the discussion, has any GPU-profiling/benchmarking been done across vendors to see what impact the shader refactoring has on performance without clear coat?
On NVIDIA, warp occupancy and register count are identical both before and after this PR.
I did a quick test on my amd 6800xt, register pressure was identical and performance was the same according to radeon gpu profiler.
No obvious performance differences for me testing vs main. What's blocking this moving forward? The more general changes seem like a marked improvement in standardization and code quality.
@NthTensor It only has one approval. Having a second approval would be very helpful.
Closing as I am burned out and have no motivation to get this landed anymore.
@pcwalton once merge conflicts are resolved this should be good to merge. Do reach out if you'd like a hand with that.
Updated.
I'm comfortable with the thoroughness and expertise of the reviews here, and this isn't a controversial addition. Merging.