From cd1ba76219d89529fce40ed082c53b8aa3122644 Mon Sep 17 00:00:00 2001 From: Patrick Walton Date: Sun, 1 Oct 2023 17:07:16 -0700 Subject: [PATCH] Import the second UV map if present in glTF files. Conventionally, the second UV map (`TEXCOORD1`, `UV1`) is used for lightmap UVs. This commit allows Bevy to import them, so that a custom shader that applies lightmaps can use those UVs if desired. Note that this doesn't actually apply lightmaps to Bevy meshes; that will be a followup. It does, however, open the door to future Bevy plugins that implement baked global illumination. --- crates/bevy_gltf/src/vertex_attributes.rs | 1 + crates/bevy_pbr/src/render/mesh.rs | 9 +++++++-- crates/bevy_pbr/src/render/mesh.wgsl | 9 +++++---- crates/bevy_render/src/mesh/mesh/mod.rs | 8 ++++++++ 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/crates/bevy_gltf/src/vertex_attributes.rs b/crates/bevy_gltf/src/vertex_attributes.rs index 7c3e9b36515994..49f99241875bf3 100644 --- a/crates/bevy_gltf/src/vertex_attributes.rs +++ b/crates/bevy_gltf/src/vertex_attributes.rs @@ -263,6 +263,7 @@ pub(crate) fn convert_attribute( gltf::Semantic::Tangents => Some((Mesh::ATTRIBUTE_TANGENT, ConversionMode::Any)), gltf::Semantic::Colors(0) => Some((Mesh::ATTRIBUTE_COLOR, ConversionMode::Rgba)), gltf::Semantic::TexCoords(0) => Some((Mesh::ATTRIBUTE_UV_0, ConversionMode::TexCoord)), + gltf::Semantic::TexCoords(1) => Some((Mesh::ATTRIBUTE_UV_1, ConversionMode::TexCoord)), gltf::Semantic::Joints(0) => { Some((Mesh::ATTRIBUTE_JOINT_INDEX, ConversionMode::JointIndex)) } diff --git a/crates/bevy_pbr/src/render/mesh.rs b/crates/bevy_pbr/src/render/mesh.rs index 151bdcf31679ae..5e30bfaca856db 100644 --- a/crates/bevy_pbr/src/render/mesh.rs +++ b/crates/bevy_pbr/src/render/mesh.rs @@ -779,14 +779,19 @@ impl SpecializedMeshPipeline for MeshPipeline { vertex_attributes.push(Mesh::ATTRIBUTE_UV_0.at_shader_location(2)); } + if layout.contains(Mesh::ATTRIBUTE_UV_1) { + shader_defs.push("VERTEX_UVS_1".into()); + vertex_attributes.push(Mesh::ATTRIBUTE_UV_1.at_shader_location(3)); + } + if layout.contains(Mesh::ATTRIBUTE_TANGENT) { shader_defs.push("VERTEX_TANGENTS".into()); - vertex_attributes.push(Mesh::ATTRIBUTE_TANGENT.at_shader_location(3)); + vertex_attributes.push(Mesh::ATTRIBUTE_TANGENT.at_shader_location(4)); } if layout.contains(Mesh::ATTRIBUTE_COLOR) { shader_defs.push("VERTEX_COLORS".into()); - vertex_attributes.push(Mesh::ATTRIBUTE_COLOR.at_shader_location(4)); + vertex_attributes.push(Mesh::ATTRIBUTE_COLOR.at_shader_location(5)); } let mut bind_group_layout = match key.msaa_samples() { diff --git a/crates/bevy_pbr/src/render/mesh.wgsl b/crates/bevy_pbr/src/render/mesh.wgsl index 0755c6859e4781..84ad95dd361db2 100644 --- a/crates/bevy_pbr/src/render/mesh.wgsl +++ b/crates/bevy_pbr/src/render/mesh.wgsl @@ -16,15 +16,16 @@ struct Vertex { #ifdef VERTEX_UVS @location(2) uv: vec2, #endif +// (Alternate UVs are at location 3, but they're currently unused here.) #ifdef VERTEX_TANGENTS - @location(3) tangent: vec4, + @location(4) tangent: vec4, #endif #ifdef VERTEX_COLORS - @location(4) color: vec4, + @location(5) color: vec4, #endif #ifdef SKINNED - @location(5) joint_indices: vec4, - @location(6) joint_weights: vec4, + @location(6) joint_indices: vec4, + @location(7) joint_weights: vec4, #endif #ifdef MORPH_TARGETS @builtin(vertex_index) index: u32, diff --git a/crates/bevy_render/src/mesh/mesh/mod.rs b/crates/bevy_render/src/mesh/mesh/mod.rs index 5830e26cb04dfe..c7c3d605f52c8b 100644 --- a/crates/bevy_render/src/mesh/mesh/mod.rs +++ b/crates/bevy_render/src/mesh/mesh/mod.rs @@ -146,6 +146,14 @@ impl Mesh { pub const ATTRIBUTE_UV_0: MeshVertexAttribute = MeshVertexAttribute::new("Vertex_Uv", 2, VertexFormat::Float32x2); + /// Alternate texture coordinates for the vertex. Use in conjuction with + /// [`Mesh::insert_attribute`]. + /// + /// Typically, these are used for lightmaps, textures that provide + /// precomputed illumination. + pub const ATTRIBUTE_UV_1: MeshVertexAttribute = + MeshVertexAttribute::new("Vertex_Uv_1", 2, VertexFormat::Float32x2); + /// The direction of the vertex tangent. Used for normal mapping. /// Usually generated with [`generate_tangents`](Mesh::generate_tangents). pub const ATTRIBUTE_TANGENT: MeshVertexAttribute =