-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
Forward decals (port of bevy_contact_projective_decals) #16600
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
| /// | ||
| /// Decreasing this value will cause the decal to blend only to surfaces closer to it. | ||
| /// | ||
| /// Units are in meters. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Units are in meters.
I think?
This commit adds support for *decal projectors* to Bevy, allowing for textures to be projected on top of geometry. Decal projectors are clusterable objects, just as punctual lights and light probes are. This means that decals are only evaluated for objects within the conservative bounds of the projector, and they don't require a second pass. These clustered decals require support for bindless textures and as such currently don't work on WebGL 2, WebGPU, macOS, or iOS. For an alternative that doesn't require bindless, see PR bevyengine#16600. I believe that both contact projective decals in bevyengine#16600 and clustered decals are desirable to have in Bevy. Contact projective decals offer broader hardware and driver support, while clustered decals don't require the creation of bounding geometry. A new example, `decal_projectors`, has been added, which demonstrates multiple decals on a rotating object. The decal projectors can be scaled and rotated with the mouse. There are several limitations of this initial patch that can be addressed in follow-ups: 1. There's no way to specify the Z-index of decals. That is, the order in which multiple decals are blended on top of one another is arbitrary. A follow-up could introduce some sort of Z-index field so that artists can specify that some decals should be blended on top of others. 2. Decals don't take the normal of the surface they're projected onto into account. Most decal implementations in other engines have a feature whereby the angle between the decal projector and the normal of the surface must be within some threshold for the decal to appear. Often, artists can specify a fade-off range for a smooth transition between oblique surfaces and aligned surfaces. 3. There's no distance-based fadeoff toward the end of the projector range. Many decal implementations have this.
pcwalton
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I got:
2025-01-12T01:11:09.471156Z ERROR bevy_render::render_resource::pipeline_cache: failed to process shader:
error: failed to build a valid final module: Function [74] 'bevy_pbr::decal::forward::get_forward_decal_info' is invalid
┌─ crates\bevy_pbr\src\decal\forward_decal.wgsl:22:1
│
22 │ ╭ fn get_forward_decal_info(in: bevy_pbr::forward_io::VertexOutput) -> ForwardDecalInformation {
23 │ │ let world_from_local = bevy_pbr::mesh_functions::get_world_from_local(in.instance_index);
24 │ │ let scale = (world_from_local * vec4(1.0, 1.0, 1.0, 0.0)).xyz;
25 │ │ let scaled_tangent = vec4(in.world_tangent.xyz / scale, in.world_tangent.w);
· │
44 │ │ let uv = bevy_pbr::parallax_mapping::parallaxed_uv(
│ │ ╭──────────────^
45 │ │ │ normal_depth,
46 │ │ │ 1.0,
47 │ │ │ 0u,
48 │ │ │ in.uv,
49 │ │ │ Vt,
│ │ ╰──────────^ invalid function call
· │ │
54 │ │
55 │ │ return ForwardDecalInformation(world_position, uv, alpha);
│ ╰────────────────────────────────────────────────────────────────^ naga::Function [74]
│
= Call to [72] is invalid
= Requires 6 arguments, but 5 are provided
| wasm = true | ||
|
|
||
| [[example]] | ||
| name = "decal" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think perhaps we should either rename this to forward_decal, or else add support for toggling between forward decals and decal projectors from #17315 to this example..
|
|
||
| fn alpha_mode(&self) -> crate::AlphaMode { | ||
| B::alpha_mode(&self.base) | ||
| fn alpha_mode(&self) -> AlphaMode { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is technically a breaking change and should be documented as such.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not a breaking change, because E::alpha_mode() did not exist until now.
|
Updated the PR, but I don't know why bevy_contact_projective_decals is calling parallaxed_uv() which samples the material's depth map, which for custom materials won't exist, and for standard material will probably be a placeholder. |
| base_color_texture: Some(asset_server.load("textures/uv_checker_bw.png")), | ||
| ..default() | ||
| }, | ||
| extension: ForwardDecalMaterialExt { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| extension: ForwardDecalMaterialExt { | |
| // The decal material is implemented as an extended material | |
| // The default implementation extends the StandardMaterial so decals are rendered using PBR | |
| extension: ForwardDecalMaterialExt { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ehh don't think this is quite accurate. I left some pretty detailed docs on the decal extension stuff, I'd rather people read that.
It's more like you can use ~any material, but you need to wrap it in the extension for CPU-side stuff, and also make some changes in the shader that StandardMaterial already has setup.
|
I suggested a few comments for the example. They don't need to be used verbatim, but a few comments like those would be nice. |
|
Not sure if it's related to this PR, but a few examples are broken when running this PR https://pixel-eagle.com/project/B25A040A-A980-4602-B90C-D480AB84076D?filter=PR-16600 |
|
I doubt it's related, probably just non-deterministic examples. |
Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
This commit adds support for *decal projectors* to Bevy, allowing for textures to be projected on top of geometry. Decal projectors are clusterable objects, just as punctual lights and light probes are. This means that decals are only evaluated for objects within the conservative bounds of the projector, and they don't require a second pass. These clustered decals require support for bindless textures and as such currently don't work on WebGL 2, WebGPU, macOS, or iOS. For an alternative that doesn't require bindless, see PR #16600. I believe that both contact projective decals in #16600 and clustered decals are desirable to have in Bevy. Contact projective decals offer broader hardware and driver support, while clustered decals don't require the creation of bounding geometry. A new example, `decal_projectors`, has been added, which demonstrates multiple decals on a rotating object. The decal projectors can be scaled and rotated with the mouse. There are several limitations of this initial patch that can be addressed in follow-ups: 1. There's no way to specify the Z-index of decals. That is, the order in which multiple decals are blended on top of one another is arbitrary. A follow-up could introduce some sort of Z-index field so that artists can specify that some decals should be blended on top of others. 2. Decals don't take the normal of the surface they're projected onto into account. Most decal implementations in other engines have a feature whereby the angle between the decal projector and the normal of the surface must be within some threshold for the decal to appear. Often, artists can specify a fade-off range for a smooth transition between oblique surfaces and aligned surfaces. 3. There's no distance-based fadeoff toward the end of the projector range. Many decal implementations have this. This addresses #2401. ## Showcase 
…6600) # Objective - Implement ForwardDecal as outlined in bevyengine#2401 ## Solution - Port https://github.com/naasblod/bevy_contact_projective_decals, and cleanup the API a little. ## Testing - Ran the new decal example. --- ## Showcase  ## Changelog * Added ForwardDecal and associated types * Added MaterialExtension::alpha_mode() --------- Co-authored-by: IceSentry <IceSentry@users.noreply.github.com>
This commit adds support for *decal projectors* to Bevy, allowing for textures to be projected on top of geometry. Decal projectors are clusterable objects, just as punctual lights and light probes are. This means that decals are only evaluated for objects within the conservative bounds of the projector, and they don't require a second pass. These clustered decals require support for bindless textures and as such currently don't work on WebGL 2, WebGPU, macOS, or iOS. For an alternative that doesn't require bindless, see PR bevyengine#16600. I believe that both contact projective decals in bevyengine#16600 and clustered decals are desirable to have in Bevy. Contact projective decals offer broader hardware and driver support, while clustered decals don't require the creation of bounding geometry. A new example, `decal_projectors`, has been added, which demonstrates multiple decals on a rotating object. The decal projectors can be scaled and rotated with the mouse. There are several limitations of this initial patch that can be addressed in follow-ups: 1. There's no way to specify the Z-index of decals. That is, the order in which multiple decals are blended on top of one another is arbitrary. A follow-up could introduce some sort of Z-index field so that artists can specify that some decals should be blended on top of others. 2. Decals don't take the normal of the surface they're projected onto into account. Most decal implementations in other engines have a feature whereby the angle between the decal projector and the normal of the surface must be within some threshold for the decal to appear. Often, artists can specify a fade-off range for a smooth transition between oblique surfaces and aligned surfaces. 3. There's no distance-based fadeoff toward the end of the projector range. Many decal implementations have this. This addresses bevyengine#2401. ## Showcase 
|
Thank you to everyone involved with the authoring or reviewing of this PR! This work is relatively important and needs release notes! Head over to bevyengine/bevy-website#1980 if you'd like to help out. |
Objective
Solution
Testing
Showcase
Changelog