#define_import_path bevy_pbr::skinning #import bevy_pbr::mesh_types::SkinnedMesh #ifdef SKINNED @group(1) @binding(1) var joint_matrices: SkinnedMesh; // An array of matrices specifying the joint positions from the previous frame. // // This is used for motion vector computation. // // If this is the first frame, or we're otherwise prevented from using data from // the previous frame, this is simply the same as `joint_matrices` above. @group(1) @binding(6) var prev_joint_matrices: SkinnedMesh; fn skin_model( indexes: vec4, weights: vec4, ) -> mat4x4 { return weights.x * joint_matrices.data[indexes.x] + weights.y * joint_matrices.data[indexes.y] + weights.z * joint_matrices.data[indexes.z] + weights.w * joint_matrices.data[indexes.w]; } // Returns the skinned position of a vertex with the given weights from the // previous frame. // // This is used for motion vector computation. fn skin_prev_model( indexes: vec4, weights: vec4, ) -> mat4x4 { return weights.x * prev_joint_matrices.data[indexes.x] + weights.y * prev_joint_matrices.data[indexes.y] + weights.z * prev_joint_matrices.data[indexes.z] + weights.w * prev_joint_matrices.data[indexes.w]; } fn inverse_transpose_3x3m(in: mat3x3) -> mat3x3 { let x = cross(in[1], in[2]); let y = cross(in[2], in[0]); let z = cross(in[0], in[1]); let det = dot(in[2], z); return mat3x3( x / det, y / det, z / det ); } fn skin_normals( world_from_local: mat4x4, normal: vec3, ) -> vec3 { return normalize( inverse_transpose_3x3m( mat3x3( world_from_local[0].xyz, world_from_local[1].xyz, world_from_local[2].xyz ) ) * normal ); } #endif