Skip to content

Commit 910e405

Browse files
authored
Allow prepass to run without ATTRIBUTE_NORMAL (#17881)
# Objective Allow prepass to run without ATTRIBUTE_NORMAL. This is needed for custom materials with non-standard vertex attributes. For example a voxel material with manually packed vertex data. Fixes #13054. This PR covers the first part of the **stale** PR #13569 to only focus on fixing #13054. ## Solution - Only push normals `vertex_attributes` when the layout contains `Mesh::ATTRIBUTE_NORMAL` ## Testing - Did you test these changes? If so, how? **Tested the fix on my own project with a mesh without normal attribute.** - Are there any parts that need more testing? **I don't think so.** - How can other people (reviewers) test your changes? Is there anything specific they need to know? **Prepass should not be blocked on a mesh without normal attributes (with or without custom material).** - If relevant, what platforms did you test these changes on, and are there any important ones you can't test? **Probably irrelevant, but Windows/Vulkan.**
1 parent 7d7c43d commit 910e405

File tree

3 files changed

+12
-1
lines changed

3 files changed

+12
-1
lines changed

crates/bevy_pbr/src/prepass/mod.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,8 +507,15 @@ where
507507
.mesh_key
508508
.intersects(MeshPipelineKey::NORMAL_PREPASS | MeshPipelineKey::DEFERRED_PREPASS)
509509
{
510-
vertex_attributes.push(Mesh::ATTRIBUTE_NORMAL.at_shader_location(3));
511510
shader_defs.push("NORMAL_PREPASS_OR_DEFERRED_PREPASS".into());
511+
if layout.0.contains(Mesh::ATTRIBUTE_NORMAL) {
512+
shader_defs.push("VERTEX_NORMALS".into());
513+
vertex_attributes.push(Mesh::ATTRIBUTE_NORMAL.at_shader_location(3));
514+
} else if key.mesh_key.contains(MeshPipelineKey::NORMAL_PREPASS) {
515+
warn!(
516+
"The default normal prepass expects the mesh to have vertex normal attributes."
517+
);
518+
}
512519
if layout.0.contains(Mesh::ATTRIBUTE_TANGENT) {
513520
shader_defs.push("VERTEX_TANGENTS".into());
514521
vertex_attributes.push(Mesh::ATTRIBUTE_TANGENT.at_shader_location(4));

crates/bevy_pbr/src/prepass/prepass.wgsl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,7 @@ fn vertex(vertex_no_morph: Vertex) -> VertexOutput {
9696
#endif // VERTEX_UVS_B
9797

9898
#ifdef NORMAL_PREPASS_OR_DEFERRED_PREPASS
99+
#ifdef VERTEX_NORMALS
99100
#ifdef SKINNED
100101
out.world_normal = skinning::skin_normals(world_from_local, vertex.normal);
101102
#else // SKINNED
@@ -106,6 +107,7 @@ fn vertex(vertex_no_morph: Vertex) -> VertexOutput {
106107
vertex_no_morph.instance_index
107108
);
108109
#endif // SKINNED
110+
#endif // VERTEX_NORMALS
109111

110112
#ifdef VERTEX_TANGENTS
111113
out.world_tangent = mesh_functions::mesh_tangent_local_to_world(

crates/bevy_pbr/src/prepass/prepass_io.wgsl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ struct Vertex {
1515
#endif
1616

1717
#ifdef NORMAL_PREPASS_OR_DEFERRED_PREPASS
18+
#ifdef VERTEX_NORMALS
1819
@location(3) normal: vec3<f32>,
20+
#endif
1921
#ifdef VERTEX_TANGENTS
2022
@location(4) tangent: vec4<f32>,
2123
#endif

0 commit comments

Comments
 (0)