diff --git a/crates/bevy_pbr/src/render/mesh_functions.wgsl b/crates/bevy_pbr/src/render/mesh_functions.wgsl index 4757148e018a9..b4a699cddcefa 100644 --- a/crates/bevy_pbr/src/render/mesh_functions.wgsl +++ b/crates/bevy_pbr/src/render/mesh_functions.wgsl @@ -35,15 +35,20 @@ fn mesh_normal_local_to_world(vertex_normal: vec3, instance_index: u32) -> // NOTE: The mikktspace method of normal mapping requires that the world normal is // re-normalized in the vertex shader to match the way mikktspace bakes vertex tangents // and normal maps so that the exact inverse process is applied when shading. Blender, Unity, - // Unreal Engine, Godot, and more all use the mikktspace method. Do not change this code - // unless you really know what you are doing. + // Unreal Engine, Godot, and more all use the mikktspace method. + // We only skip normalization for invalid normals so that they don't become NaN. + // Do not change this code unless you really know what you are doing. // http://www.mikktspace.com/ - return normalize( - mat2x4_f32_to_mat3x3_unpack( - mesh[instance_index].inverse_transpose_model_a, - mesh[instance_index].inverse_transpose_model_b, - ) * vertex_normal - ); + if any(vertex_normal != vec3(0.0)) { + return normalize( + mat2x4_f32_to_mat3x3_unpack( + mesh[instance_index].inverse_transpose_model_a, + mesh[instance_index].inverse_transpose_model_b, + ) * vertex_normal + ); + } else { + return vertex_normal; + } } // Calculates the sign of the determinant of the 3x3 model matrix based on a @@ -59,19 +64,24 @@ fn mesh_tangent_local_to_world(model: mat4x4, vertex_tangent: vec4, in // NOTE: The mikktspace method of normal mapping requires that the world tangent is // re-normalized in the vertex shader to match the way mikktspace bakes vertex tangents // and normal maps so that the exact inverse process is applied when shading. Blender, Unity, - // Unreal Engine, Godot, and more all use the mikktspace method. Do not change this code - // unless you really know what you are doing. + // Unreal Engine, Godot, and more all use the mikktspace method. + // We only skip normalization for invalid tangents so that they don't become NaN. + // Do not change this code unless you really know what you are doing. // http://www.mikktspace.com/ - return vec4( - normalize( - mat3x3( - model[0].xyz, - model[1].xyz, - model[2].xyz - ) * vertex_tangent.xyz - ), - // NOTE: Multiplying by the sign of the determinant of the 3x3 model matrix accounts for - // situations such as negative scaling. - vertex_tangent.w * sign_determinant_model_3x3m(instance_index) - ); + if any(vertex_tangent != vec4(0.0)) { + return vec4( + normalize( + mat3x3( + model[0].xyz, + model[1].xyz, + model[2].xyz + ) * vertex_tangent.xyz + ), + // NOTE: Multiplying by the sign of the determinant of the 3x3 model matrix accounts for + // situations such as negative scaling. + vertex_tangent.w * sign_determinant_model_3x3m(instance_index) + ); + } else { + return vertex_tangent; + } }