Skip to content

Tangents are not updated when transforming a Mesh #17170

Closed
@MatrixDev

Description

@MatrixDev

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");

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-RenderingDrawing game state to the screenC-BugAn unexpected or incorrect behaviorD-StraightforwardSimple bug fixes and API improvements, docs, test and examplesS-Ready-For-ImplementationThis issue is ready for an implementation PR. Go for it!

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions