Notes on adding a bevy_pbr_types
crate
#18875
greeble-dev
started this conversation in
Ideas
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
These notes document my attempt at moving parts of
bevy_pbr
into a newbevy_pbr_types
crate.Why?
I want to make
bevy_gltf
less dependent on render crates likebevy_pbr
. This would be good for compile times and other things - see my previous notes for more info.A secondary goal is to document options for the render crate restructure. I feel that working through one narrow case in full can surface useful information, and solving problems for one crate can benefit other crates.
Also, I just really like refactoring things. This is a normal hobby enjoyed by normal people such as myself.
How?
bevy_gltf
mostly wants to construct component and asset data defined inbevy_pbr
- it doesn't need 95% of the code. So I moved these components and assets into a newbevy_pbr_types
crate - thenbevy_gltf
depends only on this crate and notbevy_pbr
.StandardMaterial
The biggest hurdle is
StandardMaterial
.bevy_gltf
just wants to construct it as an asset, but the same struct also does bind group layout. This is required by theMaterial
trait, which is bound onAsset + AsBindGroup
.We don't want to pull all the bind group stuff into
bevy_pbr_types
- instead we wantStandardMaterial
to be just anAsset
and let something else do the rest.First, I changed
Material
to remove theAsset
bound. Instead it links to an asset type, and requires afrom_source_asset
method to construct itself from that asset:This means
MeshMaterial3d
can point to anAsset
instead of aMaterial
:Now any
Asset
type can be a material, and it's up to the renderer internals to say how that type gets turned into aMaterial
.But at this point we haven't achieved much since
StandardMaterial
still implements bothAsset
andMaterial
.Next I made a duplicate of
StandardMaterial
calledStandardMaterialInternal
(which is obviously bad, but I'll get to that later).StandardMaterial
is anAsset
.StandardMaterialInternal
is aMaterial
+ bind group layout, and gets afrom_source_asset
implementation that takesStandardMaterial
:Once that's all done,
StandardMaterial
andMeshMaterial3d
can move tobevy_pbr_types
.Problems
Duplicating the whole of
StandardMaterial
is a big oof. There's also some boilerplate elsewhere - various custom materials still implement bothAsset
andMaterial
, but need this faff to link them together:In practice the only thing that calls
from_source_asset
isPreparedMaterial::prepare_asset
, which immediately turns the struct into uniforms and bind groups and then throws it away. If that work can be done without the intermediate struct then a lot of the duplication and boilerplate can disappear.Another issue is that users might be confused by
MeshMaterial3d<M: Asset>
, since there's no indication of what types are actually compatible. One solution might be to add an emptyMaterialAsset
trait just to make the dependency clear, but that means yet more boilerplate for material implementors.Light Components
bevy_gltf
wants to constructPointLight
,DirectionalLight
andSpotLight
components. These are fairly plain data, except they're tied to renderer internals by required components and hooks.The required components can move to
PbrPlugin::build
, although it's a bit ugly:In theory the
on_add
hook can also movePbrPlugin::build
:But I couldn't get that working. It seems to register fine but never triggers.
register_component_hooks_by_id
also didn't work as the id couldn't be found. So for now I've left theon_add
hook on the component.The Rest
Various types and consts also moved to
bevy_pbr_types
, becausebevy_gltf
uses them directly or they're used byStandardMaterial
or the light components. These were all simple cut and pastes.And We're Done?
Full branch is here: main...greeble-dev:bevy:gltf-pbr-types
So Was It All Worth It?
Maybe. The immediate goal is achieved, although there's only a slight improvement in build times since it hasn't reduced the critical path by much.
The main issue is whether the material changes are a good idea. Adding all that faff and boilerplate is bad if the only goal is reducing
bevy_gltf
dependencies. But maybe they end up aligning with other efforts to refactor materials and make them more data-driven.What's Next?
bevy_pbr_types
andbevy_gltf
are still dependent onbevy_render
. This could be solved by creatingbevy_render_types
, but I don't currently have any plans to pull that thread.Beta Was this translation helpful? Give feedback.
All reactions