use alpha mask even when unlit (#6047)
# Objective - Alpha mask was previously ignored when using an unlit material. - Fixes https://github.com/bevyengine/bevy/issues/4479 ## Solution - Extract the alpha discard to a separate function and use it when unlit is true ## Notes I tried calling `alpha_discard()` before the `if` in pbr.wgsl, but I had errors related to having a `discard` at the beginning before doing the texture sampling. I'm not sure if there's a way to fix that instead of having the function being called in 2 places.
This commit is contained in:
		
							parent
							
								
									8073362039
								
							
						
					
					
						commit
						197392a2cd
					
				| @ -89,6 +89,8 @@ fn fragment(in: FragmentInput) -> @location(0) vec4<f32> { | ||||
|         pbr_input.V = calculate_view(in.world_position, pbr_input.is_orthographic); | ||||
| 
 | ||||
|         output_color = tone_mapping(pbr(pbr_input)); | ||||
|     } else { | ||||
|         output_color = alpha_discard(material, output_color); | ||||
|     } | ||||
| 
 | ||||
|     return output_color; | ||||
|  | ||||
| @ -1,5 +1,23 @@ | ||||
| #define_import_path bevy_pbr::pbr_functions | ||||
| 
 | ||||
| fn alpha_discard(material: StandardMaterial, output_color: vec4<f32>) -> vec4<f32>{ | ||||
|     var color = output_color; | ||||
|     if ((material.flags & STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE) != 0u) { | ||||
|         // NOTE: If rendering as opaque, alpha should be ignored so set to 1.0 | ||||
|         color.a = 1.0; | ||||
|     } else if ((material.flags & STANDARD_MATERIAL_FLAGS_ALPHA_MODE_MASK) != 0u) { | ||||
|         if (color.a >= material.alpha_cutoff) { | ||||
|             // NOTE: If rendering as masked alpha and >= the cutoff, render as fully opaque | ||||
|             color.a = 1.0; | ||||
|         } else { | ||||
|             // NOTE: output_color.a < in.material.alpha_cutoff should not is not rendered | ||||
|             // NOTE: This and any other discards mean that early-z testing cannot be done! | ||||
|             discard; | ||||
|         } | ||||
|     } | ||||
|     return color; | ||||
| } | ||||
| 
 | ||||
| // NOTE: This ensures that the world_normal is normalized and if | ||||
| // vertex tangents and normal maps then normal mapping may be applied. | ||||
| fn prepare_normal( | ||||
| @ -142,19 +160,7 @@ fn pbr( | ||||
| 
 | ||||
|     let occlusion = in.occlusion; | ||||
| 
 | ||||
|     if ((in.material.flags & STANDARD_MATERIAL_FLAGS_ALPHA_MODE_OPAQUE) != 0u) { | ||||
|         // NOTE: If rendering as opaque, alpha should be ignored so set to 1.0 | ||||
|         output_color.a = 1.0; | ||||
|     } else if ((in.material.flags & STANDARD_MATERIAL_FLAGS_ALPHA_MODE_MASK) != 0u) { | ||||
|         if (output_color.a >= in.material.alpha_cutoff) { | ||||
|             // NOTE: If rendering as masked alpha and >= the cutoff, render as fully opaque | ||||
|             output_color.a = 1.0; | ||||
|         } else { | ||||
|             // NOTE: output_color.a < in.material.alpha_cutoff should not is not rendered | ||||
|             // NOTE: This and any other discards mean that early-z testing cannot be done! | ||||
|             discard; | ||||
|         } | ||||
|     } | ||||
|     output_color = alpha_discard(in.material, output_color); | ||||
| 
 | ||||
|     // Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886" | ||||
|     let NdotV = max(dot(in.N, in.V), 0.0001); | ||||
| @ -247,3 +253,4 @@ fn tone_mapping(in: vec4<f32>) -> vec4<f32> { | ||||
|     // Not needed with sRGB buffer | ||||
|     // output_color.rgb = pow(output_color.rgb, vec3(1.0 / 2.2)); | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -44,6 +44,21 @@ fn setup( | ||||
|         transform: Transform::from_xyz(1.0, 0.5, -1.5), | ||||
|         ..default() | ||||
|     }); | ||||
|     // transparent unlit sphere, uses `alpha_mode: Mask(f32)`
 | ||||
|     commands.spawn(PbrBundle { | ||||
|         mesh: meshes.add(Mesh::from(shape::Icosphere { | ||||
|             radius: 0.5, | ||||
|             subdivisions: 3, | ||||
|         })), | ||||
|         material: materials.add(StandardMaterial { | ||||
|             base_color: Color::rgba(0.2, 0.7, 0.1, 0.0), | ||||
|             alpha_mode: AlphaMode::Mask(0.5), | ||||
|             unlit: true, | ||||
|             ..default() | ||||
|         }), | ||||
|         transform: Transform::from_xyz(-1.0, 0.5, -1.5), | ||||
|         ..default() | ||||
|     }); | ||||
|     // transparent cube, uses `alpha_mode: Blend`
 | ||||
|     commands.spawn(PbrBundle { | ||||
|         mesh: meshes.add(Mesh::from(shape::Cube { size: 1.0 })), | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Charles
						Charles