Skip to content

Commit f2dd40a

Browse files
committed
Revert "bevy_pbr: Fix tangent and normal normalization (bevyengine#5666)"
This reverts commit 681c9c6.
1 parent 661277b commit f2dd40a

File tree

4 files changed

+18
-59
lines changed

4 files changed

+18
-59
lines changed

crates/bevy_pbr/src/render/mesh.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use bevy_ecs::{
1111
query::ROQueryItem,
1212
system::{lifetimeless::*, SystemParamItem, SystemState},
1313
};
14-
use bevy_math::{Mat3A, Mat4, Vec2};
14+
use bevy_math::{Mat4, Vec2};
1515
use bevy_reflect::TypeUuid;
1616
use bevy_render::{
1717
extract_component::{ComponentUniforms, DynamicUniformIndex, UniformComponentPlugin},
@@ -122,9 +122,6 @@ bitflags::bitflags! {
122122
#[repr(transparent)]
123123
struct MeshFlags: u32 {
124124
const SHADOW_RECEIVER = (1 << 0);
125-
// Indicates the sign of the determinant of the 3x3 model matrix. If the sign is positive,
126-
// then the flag should be set, else it should not be set.
127-
const SIGN_DETERMINANT_MODEL_3X3 = (1 << 31);
128125
const NONE = 0;
129126
const UNINITIALIZED = 0xFFFF;
130127
}
@@ -151,16 +148,13 @@ pub fn extract_meshes(
151148

152149
for (entity, _, transform, handle, not_receiver, not_caster) in visible_meshes {
153150
let transform = transform.compute_matrix();
154-
let mut flags = if not_receiver.is_some() {
155-
MeshFlags::empty()
151+
let shadow_receiver_flags = if not_receiver.is_some() {
152+
MeshFlags::empty().bits
156153
} else {
157-
MeshFlags::SHADOW_RECEIVER
154+
MeshFlags::SHADOW_RECEIVER.bits
158155
};
159-
if Mat3A::from_mat4(transform).determinant().is_sign_positive() {
160-
flags |= MeshFlags::SIGN_DETERMINANT_MODEL_3X3;
161-
}
162156
let uniform = MeshUniform {
163-
flags: flags.bits,
157+
flags: shadow_receiver_flags,
164158
transform,
165159
inverse_transpose_model: transform.inverse().transpose(),
166160
};

crates/bevy_pbr/src/render/mesh_functions.wgsl

+11-38
Original file line numberDiff line numberDiff line change
@@ -17,47 +17,20 @@ fn mesh_position_local_to_clip(model: mat4x4<f32>, vertex_position: vec4<f32>) -
1717
}
1818

1919
fn mesh_normal_local_to_world(vertex_normal: vec3<f32>) -> vec3<f32> {
20-
// NOTE: The mikktspace method of normal mapping requires that the world normal is
21-
// re-normalized in the vertex shader to match the way mikktspace bakes vertex tangents
22-
// and normal maps so that the exact inverse process is applied when shading. Blender, Unity,
23-
// Unreal Engine, Godot, and more all use the mikktspace method. Do not change this code
24-
// unless you really know what you are doing.
25-
// http://www.mikktspace.com/
26-
return normalize(
27-
mat3x3<f32>(
28-
mesh.inverse_transpose_model[0].xyz,
29-
mesh.inverse_transpose_model[1].xyz,
30-
mesh.inverse_transpose_model[2].xyz
31-
) * vertex_normal
32-
);
33-
}
34-
35-
// Calculates the sign of the determinant of the 3x3 model matrix based on a
36-
// mesh flag
37-
fn sign_determinant_model_3x3() -> f32 {
38-
// bool(u32) is false if 0u else true
39-
// f32(bool) is 1.0 if true else 0.0
40-
// * 2.0 - 1.0 remaps 0.0 or 1.0 to -1.0 or 1.0 respectively
41-
return f32(bool(mesh.flags & MESH_FLAGS_SIGN_DETERMINANT_MODEL_3X3_BIT)) * 2.0 - 1.0;
20+
return mat3x3<f32>(
21+
mesh.inverse_transpose_model[0].xyz,
22+
mesh.inverse_transpose_model[1].xyz,
23+
mesh.inverse_transpose_model[2].xyz
24+
) * vertex_normal;
4225
}
4326

4427
fn mesh_tangent_local_to_world(model: mat4x4<f32>, vertex_tangent: vec4<f32>) -> vec4<f32> {
45-
// NOTE: The mikktspace method of normal mapping requires that the world tangent is
46-
// re-normalized in the vertex shader to match the way mikktspace bakes vertex tangents
47-
// and normal maps so that the exact inverse process is applied when shading. Blender, Unity,
48-
// Unreal Engine, Godot, and more all use the mikktspace method. Do not change this code
49-
// unless you really know what you are doing.
50-
// http://www.mikktspace.com/
5128
return vec4<f32>(
52-
normalize(
53-
mat3x3<f32>(
54-
model[0].xyz,
55-
model[1].xyz,
56-
model[2].xyz
57-
) * vertex_tangent.xyz
58-
),
59-
// NOTE: Multiplying by the sign of the determinant of the 3x3 model matrix accounts for
60-
// situations such as negative scaling.
61-
vertex_tangent.w * sign_determinant_model_3x3()
29+
mat3x3<f32>(
30+
model[0].xyz,
31+
model[1].xyz,
32+
model[2].xyz
33+
) * vertex_tangent.xyz,
34+
vertex_tangent.w
6235
);
6336
}

crates/bevy_pbr/src/render/mesh_types.wgsl

-2
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,3 @@ struct SkinnedMesh {
1414
#endif
1515

1616
let MESH_FLAGS_SHADOW_RECEIVER_BIT: u32 = 1u;
17-
// 2^31 - if the flag is set, the sign is positive, else it is negative
18-
let MESH_FLAGS_SIGN_DETERMINANT_MODEL_3X3_BIT: u32 = 2147483648u;

crates/bevy_pbr/src/render/pbr_functions.wgsl

+2-8
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,7 @@ fn apply_normal_mapping(
5252
uv: vec2<f32>,
5353
#endif
5454
) -> vec3<f32> {
55-
// NOTE: The mikktspace method of normal mapping explicitly requires that the world normal NOT
56-
// be re-normalized in the fragment shader. This is primarily to match the way mikktspace
57-
// bakes vertex tangents and normal maps so that this is the exact inverse. Blender, Unity,
58-
// Unreal Engine, Godot, and more all use the mikktspace method. Do not change this code
59-
// unless you really know what you are doing.
60-
// http://www.mikktspace.com/
61-
var N: vec3<f32> = world_normal;
55+
var N: vec3<f32> = normalize(world_normal);
6256

6357
#ifdef VERTEX_TANGENTS
6458
#ifdef STANDARDMATERIAL_NORMAL_MAP
@@ -256,7 +250,7 @@ fn pbr(
256250
fn tone_mapping(in: vec4<f32>) -> vec4<f32> {
257251
// tone_mapping
258252
return vec4<f32>(reinhard_luminance(in.rgb), in.a);
259-
253+
260254
// Gamma correction.
261255
// Not needed with sRGB buffer
262256
// output_color.rgb = pow(output_color.rgb, vec3(1.0 / 2.2));

0 commit comments

Comments
 (0)