Skip to content
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

Tangents are not updated when transforming a Mesh #17170

Open
MatrixDev opened this issue Jan 5, 2025 · 0 comments
Open

Tangents are not updated when transforming a Mesh #17170

MatrixDev opened this issue Jan 5, 2025 · 0 comments
Labels
A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it!

Comments

@MatrixDev
Copy link

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");
@MatrixDev MatrixDev added C-Bug An unexpected or incorrect behavior S-Needs-Triage This issue needs to be labelled labels Jan 5, 2025
@BenjaminBrienen BenjaminBrienen added A-Rendering Drawing game state to the screen S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it! D-Straightforward Simple bug fixes and API improvements, docs, test and examples and removed S-Needs-Triage This issue needs to be labelled labels Jan 5, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-Rendering Drawing game state to the screen C-Bug An unexpected or incorrect behavior D-Straightforward Simple bug fixes and API improvements, docs, test and examples S-Ready-For-Implementation This issue is ready for an implementation PR. Go for it!
Projects
None yet
Development

No branches or pull requests

2 participants