Fix handling of double_sided for normal maps (#10326)
				
					
				
			# Objective Right now, we flip the `world_normal` in response to `double_sided && !is_front`, however when calculating `N` from tangents and the normal map, we don't flip the normal read from the normal map, which produces extremely weird results. ## Solution - Pass `double_sided` and `is_front` flags to the `apply_normal_mapping()` function and use them to conditionally flip `Nt` ## Comparison Note: These are from a custom scene running with the `transmission` branch, (#8015) I noticed lighting got pretty weird for the back side of translucent `double_sided` materials whenever I added a normal map. ### Before <img width="1392" alt="Screenshot 2023-10-31 at 01 26 06" src="https://github.com/bevyengine/bevy/assets/418473/d5f8c9c3-aca1-4c2f-854d-f0d0fd2fb19a"> ### After <img width="1392" alt="Screenshot 2023-10-31 at 01 25 42" src="https://github.com/bevyengine/bevy/assets/418473/fa0e1aa2-19ad-4c27-bb08-37299d97971c"> --- ## Changelog - Fixed a bug where `StandardMaterial::double_sided` would interact incorrectly with normal maps, producing broken results.
This commit is contained in:
		
							parent
							
								
									3628e09045
								
							
						
					
					
						commit
						dc1f76d9a2
					
				| @ -148,6 +148,8 @@ fn pbr_input_from_standard_material( | |||||||
|         pbr_input.N = pbr_functions::apply_normal_mapping( |         pbr_input.N = pbr_functions::apply_normal_mapping( | ||||||
|             pbr_bindings::material.flags, |             pbr_bindings::material.flags, | ||||||
|             pbr_input.world_normal, |             pbr_input.world_normal, | ||||||
|  |             double_sided, | ||||||
|  |             is_front, | ||||||
| #ifdef VERTEX_TANGENTS | #ifdef VERTEX_TANGENTS | ||||||
| #ifdef STANDARDMATERIAL_NORMAL_MAP | #ifdef STANDARDMATERIAL_NORMAL_MAP | ||||||
|             in.world_tangent, |             in.world_tangent, | ||||||
|  | |||||||
| @ -61,6 +61,8 @@ fn prepare_world_normal( | |||||||
| fn apply_normal_mapping( | fn apply_normal_mapping( | ||||||
|     standard_material_flags: u32, |     standard_material_flags: u32, | ||||||
|     world_normal: vec3<f32>, |     world_normal: vec3<f32>, | ||||||
|  |     double_sided: bool, | ||||||
|  |     is_front: bool, | ||||||
| #ifdef VERTEX_TANGENTS | #ifdef VERTEX_TANGENTS | ||||||
| #ifdef STANDARDMATERIAL_NORMAL_MAP | #ifdef STANDARDMATERIAL_NORMAL_MAP | ||||||
|     world_tangent: vec4<f32>, |     world_tangent: vec4<f32>, | ||||||
| @ -106,6 +108,11 @@ fn apply_normal_mapping( | |||||||
|     if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_FLIP_NORMAL_MAP_Y) != 0u { |     if (standard_material_flags & pbr_types::STANDARD_MATERIAL_FLAGS_FLIP_NORMAL_MAP_Y) != 0u { | ||||||
|         Nt.y = -Nt.y; |         Nt.y = -Nt.y; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     if double_sided && !is_front { | ||||||
|  |         Nt = -Nt; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|     // NOTE: The mikktspace method of normal mapping applies maps the tangent-space normal from |     // NOTE: The mikktspace method of normal mapping applies maps the tangent-space normal from | ||||||
|     // the normal map texture in this way to be an EXACT inverse of how the normal map baker |     // the normal map texture in this way to be an EXACT inverse of how the normal map baker | ||||||
|     // calculates the normal maps so there is no error introduced. Do not change this code |     // calculates the normal maps so there is no error introduced. Do not change this code | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Marco Buono
						Marco Buono