Closed
Description
Bevy version
0.15.1
What you did
Rotated mesh after generating tangents.
What went wrong
Everything is updated except tangents.
This happens because tangents are Float32x4
but all Mesh
functions assume they are Float32x3
.
// crates/bevy_mesh/src/mesh.rs
/// The direction of the vertex tangent. Used for normal mapping.
/// Usually generated with [`generate_tangents`](Mesh::generate_tangents) or
/// [`with_generated_tangents`](Mesh::with_generated_tangents).
///
/// The format of this attribute is [`VertexFormat::Float32x4`].
pub const ATTRIBUTE_TANGENT: MeshVertexAttribute =
MeshVertexAttribute::new("Vertex_Tangent", 4, VertexFormat::Float32x4);
// crates/bevy_mesh/src/mesh.rs
if let Some(VertexAttributeValues::Float32x3(ref mut tangents)) =
self.attribute_mut(Mesh::ATTRIBUTE_TANGENT)
{
// Transform tangents
tangents.iter_mut().for_each(|tangent| {
*tangent = (rotation * Vec3::from_slice(tangent).normalize_or_zero()).to_array();
});
}
Additional information
Test example:
let plane = Plane3d::new(Vec3::Y, Vec2::splat(1.0));
let mesh = Mesh::from(plane).with_generated_tangents().unwrap();
let normals_old = mesh.attribute(Mesh::ATTRIBUTE_NORMAL).unwrap().clone();
let tangents_old = mesh.attribute(Mesh::ATTRIBUTE_TANGENT).unwrap().clone();
let mesh = mesh.rotated_by(Quat::from_euler(EulerRot::YXZ, 0.3, 0.3, 0.3));
let normals_new = mesh.attribute(Mesh::ATTRIBUTE_NORMAL).unwrap().clone();
let tangents_new = mesh.attribute(Mesh::ATTRIBUTE_TANGENT).unwrap().clone();
assert_ne!(normals_old.get_bytes(), normals_new.get_bytes(), "normals are not changed");
assert_ne!(tangents_old.get_bytes(), tangents_new.get_bytes(), "tangents are not changed");