diff --git a/content/news/2025-XX-XX-bevy-0.16/clustered-decals.png b/content/news/2025-XX-XX-bevy-0.16/clustered-decals.png new file mode 100644 index 0000000000..6f1ef79447 Binary files /dev/null and b/content/news/2025-XX-XX-bevy-0.16/clustered-decals.png differ diff --git a/content/news/2025-XX-XX-bevy-0.16/decals.png b/content/news/2025-XX-XX-bevy-0.16/decals.png new file mode 100644 index 0000000000..345e936276 Binary files /dev/null and b/content/news/2025-XX-XX-bevy-0.16/decals.png differ diff --git a/release-content/0.16/release-notes/16600_Forward_decals_port_of_bevy_contact_projective_decals.md b/release-content/0.16/release-notes/16600_Forward_decals_port_of_bevy_contact_projective_decals.md deleted file mode 100644 index 4b193a0675..0000000000 --- a/release-content/0.16/release-notes/16600_Forward_decals_port_of_bevy_contact_projective_decals.md +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/release-content/0.16/release-notes/17315_Implement_basic_clustered_decal_projectors.md b/release-content/0.16/release-notes/17315_Implement_basic_clustered_decal_projectors.md deleted file mode 100644 index 7fcdf9c771..0000000000 --- a/release-content/0.16/release-notes/17315_Implement_basic_clustered_decal_projectors.md +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/release-content/0.16/release-notes/_release-notes.toml b/release-content/0.16/release-notes/_release-notes.toml index a58e8adab1..ec4973af3b 100644 --- a/release-content/0.16/release-notes/_release-notes.toml +++ b/release-content/0.16/release-notes/_release-notes.toml @@ -93,11 +93,11 @@ prs = [17096] file_name = "17096_Anamorphic_Bloom.md" [[release_notes]] -title = "Forward decals (port of bevy_contact_projective_decals)" -authors = ["@JMS55"] -contributors = ["@IceSentry"] -prs = [16600] -file_name = "16600_Forward_decals_port_of_bevy_contact_projective_decals.md" +title = "Decals" +authors = ["@naasblod", "@JMS55", "@pcwalton"] +contributors = ["@IceSentry", "@NiseVoid", "@DGriffin91"] +prs = [16600, 17315] +file_name = "decals.md" [[release_notes]] title = "Procedural atmospheric scattering" @@ -106,13 +106,6 @@ contributors = ["@mate-h", "@atlv24", "@JMS55"] prs = [16314] file_name = "16314_Procedural_atmospheric_scattering.md" -[[release_notes]] -title = "Implement basic clustered decal projectors." -authors = ["@pcwalton"] -contributors = [] -prs = [17315] -file_name = "17315_Implement_basic_clustered_decal_projectors.md" - [[release_notes]] title = "Specular tints and maps" authors = ["@pcwalton"] diff --git a/release-content/0.16/release-notes/decals.md b/release-content/0.16/release-notes/decals.md new file mode 100644 index 0000000000..e1ab024a7d --- /dev/null +++ b/release-content/0.16/release-notes/decals.md @@ -0,0 +1,31 @@ +**Decals** are textures which can be dynamically layered on top of existing meshes, conforming to their geometry. +This has two benefits over simply changing a mesh's texture: + +1. You can add them dynamically in response to player actions. Most famously, bullet holes in FPS games use decals for this. +2. You don't need to create an entirely new texture for every combination, which makes them more efficient and flexible when creating levels with details like graffiti or cracks in building facades. + +Like many things in rendering, there are a huge number of ways to implement this feature, each with their own tradeoffs. +In Bevy 0.16, we've selected two complementary approaches: **forward decals** and **clustered decals**. + +![decals](decals.png) + +Our implementation of forward decals (or to be more precise, contact projective decals) was inspired by [Alexander Sannikovs talk on the rendering techniques of Path of Exile 2], and was upstreamed from the [`bevy_contact_projective_decals`] ecosystem crate. +Due to nature of this technique, looking at the decal from very steep angles will cause distortion. +This can be mitigated by creating textures that are bigger than the effect, giving the decal more space to stretch. +To create a forward decal, spawn a [`ForwardDecal`] entity, which uses a [`ForwardDecalMaterial`] using the [`ForwardDecalMaterialExt`] material extension. + +![clustered decals](clustered-decals.png) + +Clustered decals (or decal projectors) work by projecting images from a 1x1x1 cube onto surfaces found in the +Z direction. +They are clusterable objects, just like point lights and light probes, which means that decals are only evaluated for objects within the bounds of the projector. +To create a clustered decal, spawn a [`ClusteredDecal`] entity. + +Ultimately, forward decals offer broader hardware and driver support, while clustered decals are higher quality and don't require the creation of bounding geometry, improving performance. +Currently clustered decals require bindless textures and thus don't support WebGL2, WebGPU, iOS and Mac targets. Forward decals _are_ available on these targets. + +[Alexander Sannikovs talk on the rendering techniques of Path of Exile 2]: https://www.youtube.com/watch?v=TrHHTQqmAaM +[`bevy_contact_projective_decals`]: https://github.com/naasblod/bevy_contact_projective_decals +[`ForwardDecal`]: https://dev-docs.bevyengine.org/bevy/pbr/decal/struct.ForwardDecal.html +[`ForwardDecalMaterial`]: https://dev-docs.bevyengine.org/bevy/pbr/decal/type.ForwardDecalMaterial.html +[`ForwardDecalMaterialExt`]: https://dev-docs.bevyengine.org/bevy/pbr/decal/struct.ForwardDecalMaterialExt.html +[`ClusteredDecal`]: https://dev-docs.bevyengine.org/bevy/pbr/decal/clustered/struct.ClusteredDecal.html