diff --git a/assets/shaders/array_texture.wgsl b/assets/shaders/array_texture.wgsl index 91f4564e7f..8194a9dea1 100644 --- a/assets/shaders/array_texture.wgsl +++ b/assets/shaders/array_texture.wgsl @@ -34,20 +34,23 @@ fn fragment(in: FragmentInput) -> @location(0) vec4 { pbr_input.frag_coord = in.frag_coord; pbr_input.world_position = in.world_position; - pbr_input.world_normal = in.world_normal; + pbr_input.world_normal = prepare_world_normal( + in.world_normal, + (pbr_input.material.flags & STANDARD_MATERIAL_FLAGS_DOUBLE_SIDED_BIT) != 0u, + in.is_front, + ); pbr_input.is_orthographic = view.projection[3].w == 1.0; - pbr_input.N = prepare_normal( + pbr_input.N = apply_normal_mapping( pbr_input.material.flags, - in.world_normal, + pbr_input.world_normal, #ifdef VERTEX_TANGENTS #ifdef STANDARDMATERIAL_NORMAL_MAP in.world_tangent, #endif #endif in.uv, - in.is_front, ); pbr_input.V = calculate_view(in.world_position, pbr_input.is_orthographic); diff --git a/crates/bevy_pbr/src/render/mesh.wgsl b/crates/bevy_pbr/src/render/mesh.wgsl index 4945db8fbf..9fde8296bf 100644 --- a/crates/bevy_pbr/src/render/mesh.wgsl +++ b/crates/bevy_pbr/src/render/mesh.wgsl @@ -70,7 +70,6 @@ fn vertex(vertex: Vertex) -> VertexOutput { } struct FragmentInput { - @builtin(front_facing) is_front: bool, #import bevy_pbr::mesh_vertex_output }; diff --git a/crates/bevy_pbr/src/render/pbr.wgsl b/crates/bevy_pbr/src/render/pbr.wgsl index 1b943c666f..716ef89a43 100644 --- a/crates/bevy_pbr/src/render/pbr.wgsl +++ b/crates/bevy_pbr/src/render/pbr.wgsl @@ -69,13 +69,17 @@ fn fragment(in: FragmentInput) -> @location(0) vec4 { pbr_input.frag_coord = in.frag_coord; pbr_input.world_position = in.world_position; - pbr_input.world_normal = in.world_normal; + pbr_input.world_normal = prepare_world_normal( + in.world_normal, + (material.flags & STANDARD_MATERIAL_FLAGS_DOUBLE_SIDED_BIT) != 0u, + in.is_front, + ); pbr_input.is_orthographic = view.projection[3].w == 1.0; - pbr_input.N = prepare_normal( + pbr_input.N = apply_normal_mapping( material.flags, - in.world_normal, + pbr_input.world_normal, #ifdef VERTEX_TANGENTS #ifdef STANDARDMATERIAL_NORMAL_MAP in.world_tangent, @@ -84,7 +88,6 @@ fn fragment(in: FragmentInput) -> @location(0) vec4 { #ifdef VERTEX_UVS in.uv, #endif - in.is_front, ); pbr_input.V = calculate_view(in.world_position, pbr_input.is_orthographic); output_color = pbr(pbr_input); diff --git a/crates/bevy_pbr/src/render/pbr_functions.wgsl b/crates/bevy_pbr/src/render/pbr_functions.wgsl index 4be10410b4..58eb7023e7 100644 --- a/crates/bevy_pbr/src/render/pbr_functions.wgsl +++ b/crates/bevy_pbr/src/render/pbr_functions.wgsl @@ -23,9 +23,23 @@ fn alpha_discard(material: StandardMaterial, output_color: vec4) -> vec4, + double_sided: bool, + is_front: bool, +) -> vec3 { + var output: vec3 = world_normal; +#ifndef VERTEX_TANGENTS +#ifndef STANDARDMATERIAL_NORMAL_MAP + // NOTE: When NOT using normal-mapping, if looking at the back face of a double-sided + // material, the normal needs to be inverted. This is a branchless version of that. + output = (f32(!double_sided || is_front) * 2.0 - 1.0) * output; +#endif +#endif + return output; +} + +fn apply_normal_mapping( standard_material_flags: u32, world_normal: vec3, #ifdef VERTEX_TANGENTS @@ -36,7 +50,6 @@ fn prepare_normal( #ifdef VERTEX_UVS uv: vec2, #endif - is_front: bool, ) -> vec3 { // NOTE: The mikktspace method of normal mapping explicitly requires that the world normal NOT // be re-normalized in the fragment shader. This is primarily to match the way mikktspace @@ -57,18 +70,6 @@ fn prepare_normal( #endif #endif - if ((standard_material_flags & STANDARD_MATERIAL_FLAGS_DOUBLE_SIDED_BIT) != 0u) { - if (!is_front) { - N = -N; -#ifdef VERTEX_TANGENTS -#ifdef STANDARDMATERIAL_NORMAL_MAP - T = -T; - B = -B; -#endif -#endif - } - } - #ifdef VERTEX_TANGENTS #ifdef VERTEX_UVS #ifdef STANDARDMATERIAL_NORMAL_MAP diff --git a/crates/bevy_sprite/src/mesh2d/color_material.wgsl b/crates/bevy_sprite/src/mesh2d/color_material.wgsl index 3b5893d4ce..0e83d1487d 100644 --- a/crates/bevy_sprite/src/mesh2d/color_material.wgsl +++ b/crates/bevy_sprite/src/mesh2d/color_material.wgsl @@ -19,7 +19,6 @@ var texture_sampler: sampler; var mesh: Mesh2d; struct FragmentInput { - @builtin(front_facing) is_front: bool, #import bevy_sprite::mesh2d_vertex_output }; diff --git a/crates/bevy_sprite/src/mesh2d/mesh2d.wgsl b/crates/bevy_sprite/src/mesh2d/mesh2d.wgsl index 95adaa22f8..0be59aef75 100644 --- a/crates/bevy_sprite/src/mesh2d/mesh2d.wgsl +++ b/crates/bevy_sprite/src/mesh2d/mesh2d.wgsl @@ -55,7 +55,6 @@ fn vertex(vertex: Vertex) -> VertexOutput { } struct FragmentInput { - @builtin(front_facing) is_front: bool, #import bevy_sprite::mesh2d_vertex_output };