mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
Refactor rendering systems to use let-else
(#9870)
# Objective Some rendering system did heavy use of `if let`, and could be improved by using `let else`. ## Solution - Reduce rightward drift by using let-else over if-let - Extract value-to-key mappings to their own functions so that the system is less bloated, easier to understand - Use a `let` binding instead of untupling in closure argument to reduce indentation ## Note to reviewers Enable the "no white space diff" for easier viewing. In the "Files changed" view, click on the little cog right of the "Jump to" text, on the row where the "Review changes" button is. then enable the "Hide whitespace" checkbox and click reload.
This commit is contained in:
parent
9873c9745b
commit
47d87e49da
4 changed files with 256 additions and 264 deletions
|
@ -365,6 +365,33 @@ impl<P: PhaseItem, M: Material, const I: usize> RenderCommand<P> for SetMaterial
|
|||
}
|
||||
}
|
||||
|
||||
const fn alpha_mode_pipeline_key(alpha_mode: AlphaMode) -> MeshPipelineKey {
|
||||
match alpha_mode {
|
||||
// Premultiplied and Add share the same pipeline key
|
||||
// They're made distinct in the PBR shader, via `premultiply_alpha()`
|
||||
AlphaMode::Premultiplied | AlphaMode::Add => MeshPipelineKey::BLEND_PREMULTIPLIED_ALPHA,
|
||||
AlphaMode::Blend => MeshPipelineKey::BLEND_ALPHA,
|
||||
AlphaMode::Multiply => MeshPipelineKey::BLEND_MULTIPLY,
|
||||
AlphaMode::Mask(_) => MeshPipelineKey::MAY_DISCARD,
|
||||
_ => MeshPipelineKey::NONE,
|
||||
}
|
||||
}
|
||||
|
||||
const fn tonemapping_pipeline_key(tonemapping: Tonemapping) -> MeshPipelineKey {
|
||||
match tonemapping {
|
||||
Tonemapping::None => MeshPipelineKey::TONEMAP_METHOD_NONE,
|
||||
Tonemapping::Reinhard => MeshPipelineKey::TONEMAP_METHOD_REINHARD,
|
||||
Tonemapping::ReinhardLuminance => MeshPipelineKey::TONEMAP_METHOD_REINHARD_LUMINANCE,
|
||||
Tonemapping::AcesFitted => MeshPipelineKey::TONEMAP_METHOD_ACES_FITTED,
|
||||
Tonemapping::AgX => MeshPipelineKey::TONEMAP_METHOD_AGX,
|
||||
Tonemapping::SomewhatBoringDisplayTransform => {
|
||||
MeshPipelineKey::TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM
|
||||
}
|
||||
Tonemapping::TonyMcMapface => MeshPipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE,
|
||||
Tonemapping::BlenderFilmic => MeshPipelineKey::TONEMAP_METHOD_BLENDER_FILMIC,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn queue_material_meshes<M: Material>(
|
||||
opaque_draw_functions: Res<DrawFunctions<Opaque3d>>,
|
||||
|
@ -418,131 +445,97 @@ pub fn queue_material_meshes<M: Material>(
|
|||
if normal_prepass.is_some() {
|
||||
view_key |= MeshPipelineKey::NORMAL_PREPASS;
|
||||
}
|
||||
|
||||
if taa_settings.is_some() {
|
||||
view_key |= MeshPipelineKey::TAA;
|
||||
}
|
||||
let environment_map_loaded = environment_map.is_some_and(|map| map.is_loaded(&images));
|
||||
|
||||
let environment_map_loaded = match environment_map {
|
||||
Some(environment_map) => environment_map.is_loaded(&images),
|
||||
None => false,
|
||||
};
|
||||
if environment_map_loaded {
|
||||
view_key |= MeshPipelineKey::ENVIRONMENT_MAP;
|
||||
}
|
||||
|
||||
if !view.hdr {
|
||||
if let Some(tonemapping) = tonemapping {
|
||||
view_key |= MeshPipelineKey::TONEMAP_IN_SHADER;
|
||||
view_key |= match tonemapping {
|
||||
Tonemapping::None => MeshPipelineKey::TONEMAP_METHOD_NONE,
|
||||
Tonemapping::Reinhard => MeshPipelineKey::TONEMAP_METHOD_REINHARD,
|
||||
Tonemapping::ReinhardLuminance => {
|
||||
MeshPipelineKey::TONEMAP_METHOD_REINHARD_LUMINANCE
|
||||
}
|
||||
Tonemapping::AcesFitted => MeshPipelineKey::TONEMAP_METHOD_ACES_FITTED,
|
||||
Tonemapping::AgX => MeshPipelineKey::TONEMAP_METHOD_AGX,
|
||||
Tonemapping::SomewhatBoringDisplayTransform => {
|
||||
MeshPipelineKey::TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM
|
||||
}
|
||||
Tonemapping::TonyMcMapface => MeshPipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE,
|
||||
Tonemapping::BlenderFilmic => MeshPipelineKey::TONEMAP_METHOD_BLENDER_FILMIC,
|
||||
};
|
||||
view_key |= tonemapping_pipeline_key(*tonemapping);
|
||||
}
|
||||
if let Some(DebandDither::Enabled) = dither {
|
||||
view_key |= MeshPipelineKey::DEBAND_DITHER;
|
||||
}
|
||||
}
|
||||
|
||||
if ssao.is_some() {
|
||||
view_key |= MeshPipelineKey::SCREEN_SPACE_AMBIENT_OCCLUSION;
|
||||
}
|
||||
|
||||
let rangefinder = view.rangefinder3d();
|
||||
for visible_entity in &visible_entities.entities {
|
||||
if let Ok((material_handle, mesh_handle, mesh_transforms)) =
|
||||
let Ok((material_handle, mesh_handle, mesh_transforms)) =
|
||||
material_meshes.get(*visible_entity)
|
||||
{
|
||||
if let (Some(mesh), Some(material)) = (
|
||||
render_meshes.get(mesh_handle),
|
||||
render_materials.get(&material_handle.id()),
|
||||
) {
|
||||
let mut mesh_key =
|
||||
MeshPipelineKey::from_primitive_topology(mesh.primitive_topology)
|
||||
| view_key;
|
||||
if mesh.morph_targets.is_some() {
|
||||
mesh_key |= MeshPipelineKey::MORPH_TARGETS;
|
||||
}
|
||||
match material.properties.alpha_mode {
|
||||
AlphaMode::Blend => {
|
||||
mesh_key |= MeshPipelineKey::BLEND_ALPHA;
|
||||
}
|
||||
AlphaMode::Premultiplied | AlphaMode::Add => {
|
||||
// Premultiplied and Add share the same pipeline key
|
||||
// They're made distinct in the PBR shader, via `premultiply_alpha()`
|
||||
mesh_key |= MeshPipelineKey::BLEND_PREMULTIPLIED_ALPHA;
|
||||
}
|
||||
AlphaMode::Multiply => {
|
||||
mesh_key |= MeshPipelineKey::BLEND_MULTIPLY;
|
||||
}
|
||||
AlphaMode::Mask(_) => {
|
||||
mesh_key |= MeshPipelineKey::MAY_DISCARD;
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let Some(mesh) = render_meshes.get(mesh_handle) else {
|
||||
continue;
|
||||
};
|
||||
let Some(material) = render_materials.get(&material_handle.id()) else {
|
||||
continue;
|
||||
};
|
||||
let mut mesh_key = view_key;
|
||||
|
||||
let pipeline_id = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&material_pipeline,
|
||||
MaterialPipelineKey {
|
||||
mesh_key,
|
||||
bind_group_data: material.key.clone(),
|
||||
},
|
||||
&mesh.layout,
|
||||
);
|
||||
let pipeline_id = match pipeline_id {
|
||||
Ok(id) => id,
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
mesh_key |= MeshPipelineKey::from_primitive_topology(mesh.primitive_topology);
|
||||
|
||||
let distance = rangefinder
|
||||
.distance_translation(&mesh_transforms.transform.translation)
|
||||
+ material.properties.depth_bias;
|
||||
match material.properties.alpha_mode {
|
||||
AlphaMode::Opaque => {
|
||||
opaque_phase.add(Opaque3d {
|
||||
entity: *visible_entity,
|
||||
draw_function: draw_opaque_pbr,
|
||||
pipeline: pipeline_id,
|
||||
distance,
|
||||
batch_size: 1,
|
||||
});
|
||||
}
|
||||
AlphaMode::Mask(_) => {
|
||||
alpha_mask_phase.add(AlphaMask3d {
|
||||
entity: *visible_entity,
|
||||
draw_function: draw_alpha_mask_pbr,
|
||||
pipeline: pipeline_id,
|
||||
distance,
|
||||
batch_size: 1,
|
||||
});
|
||||
}
|
||||
AlphaMode::Blend
|
||||
| AlphaMode::Premultiplied
|
||||
| AlphaMode::Add
|
||||
| AlphaMode::Multiply => {
|
||||
transparent_phase.add(Transparent3d {
|
||||
entity: *visible_entity,
|
||||
draw_function: draw_transparent_pbr,
|
||||
pipeline: pipeline_id,
|
||||
distance,
|
||||
batch_size: 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
if mesh.morph_targets.is_some() {
|
||||
mesh_key |= MeshPipelineKey::MORPH_TARGETS;
|
||||
}
|
||||
mesh_key |= alpha_mode_pipeline_key(material.properties.alpha_mode);
|
||||
|
||||
let pipeline_id = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&material_pipeline,
|
||||
MaterialPipelineKey {
|
||||
mesh_key,
|
||||
bind_group_data: material.key.clone(),
|
||||
},
|
||||
&mesh.layout,
|
||||
);
|
||||
let pipeline_id = match pipeline_id {
|
||||
Ok(id) => id,
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let distance = rangefinder.distance_translation(&mesh_transforms.transform.translation)
|
||||
+ material.properties.depth_bias;
|
||||
match material.properties.alpha_mode {
|
||||
AlphaMode::Opaque => {
|
||||
opaque_phase.add(Opaque3d {
|
||||
entity: *visible_entity,
|
||||
draw_function: draw_opaque_pbr,
|
||||
pipeline: pipeline_id,
|
||||
distance,
|
||||
batch_size: 1,
|
||||
});
|
||||
}
|
||||
AlphaMode::Mask(_) => {
|
||||
alpha_mask_phase.add(AlphaMask3d {
|
||||
entity: *visible_entity,
|
||||
draw_function: draw_alpha_mask_pbr,
|
||||
pipeline: pipeline_id,
|
||||
distance,
|
||||
batch_size: 1,
|
||||
});
|
||||
}
|
||||
AlphaMode::Blend
|
||||
| AlphaMode::Premultiplied
|
||||
| AlphaMode::Add
|
||||
| AlphaMode::Multiply => {
|
||||
transparent_phase.add(Transparent3d {
|
||||
entity: *visible_entity,
|
||||
draw_function: draw_transparent_pbr,
|
||||
pipeline: pipeline_id,
|
||||
distance,
|
||||
batch_size: 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -346,39 +346,38 @@ pub fn extract_lights(
|
|||
|
||||
let mut point_lights_values = Vec::with_capacity(*previous_point_lights_len);
|
||||
for entity in global_point_lights.iter().copied() {
|
||||
if let Ok((point_light, cubemap_visible_entities, transform, view_visibility)) =
|
||||
let Ok((point_light, cubemap_visible_entities, transform, view_visibility)) =
|
||||
point_lights.get(entity)
|
||||
{
|
||||
if !view_visibility.get() {
|
||||
continue;
|
||||
}
|
||||
// TODO: This is very much not ideal. We should be able to re-use the vector memory.
|
||||
// However, since exclusive access to the main world in extract is ill-advised, we just clone here.
|
||||
let render_cubemap_visible_entities = cubemap_visible_entities.clone();
|
||||
point_lights_values.push((
|
||||
entity,
|
||||
(
|
||||
ExtractedPointLight {
|
||||
color: point_light.color,
|
||||
// NOTE: Map from luminous power in lumens to luminous intensity in lumens per steradian
|
||||
// for a point light. See https://google.github.io/filament/Filament.html#mjx-eqn-pointLightLuminousPower
|
||||
// for details.
|
||||
intensity: point_light.intensity / (4.0 * std::f32::consts::PI),
|
||||
range: point_light.range,
|
||||
radius: point_light.radius,
|
||||
transform: *transform,
|
||||
shadows_enabled: point_light.shadows_enabled,
|
||||
shadow_depth_bias: point_light.shadow_depth_bias,
|
||||
// The factor of SQRT_2 is for the worst-case diagonal offset
|
||||
shadow_normal_bias: point_light.shadow_normal_bias
|
||||
* point_light_texel_size
|
||||
* std::f32::consts::SQRT_2,
|
||||
spot_light_angles: None,
|
||||
},
|
||||
render_cubemap_visible_entities,
|
||||
),
|
||||
));
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
if !view_visibility.get() {
|
||||
continue;
|
||||
}
|
||||
// TODO: This is very much not ideal. We should be able to re-use the vector memory.
|
||||
// However, since exclusive access to the main world in extract is ill-advised, we just clone here.
|
||||
let render_cubemap_visible_entities = cubemap_visible_entities.clone();
|
||||
let extracted_point_light = ExtractedPointLight {
|
||||
color: point_light.color,
|
||||
// NOTE: Map from luminous power in lumens to luminous intensity in lumens per steradian
|
||||
// for a point light. See https://google.github.io/filament/Filament.html#mjx-eqn-pointLightLuminousPower
|
||||
// for details.
|
||||
intensity: point_light.intensity / (4.0 * std::f32::consts::PI),
|
||||
range: point_light.range,
|
||||
radius: point_light.radius,
|
||||
transform: *transform,
|
||||
shadows_enabled: point_light.shadows_enabled,
|
||||
shadow_depth_bias: point_light.shadow_depth_bias,
|
||||
// The factor of SQRT_2 is for the worst-case diagonal offset
|
||||
shadow_normal_bias: point_light.shadow_normal_bias
|
||||
* point_light_texel_size
|
||||
* std::f32::consts::SQRT_2,
|
||||
spot_light_angles: None,
|
||||
};
|
||||
point_lights_values.push((
|
||||
entity,
|
||||
(extracted_point_light, render_cubemap_visible_entities),
|
||||
));
|
||||
}
|
||||
*previous_point_lights_len = point_lights_values.len();
|
||||
commands.insert_or_spawn_batch(point_lights_values);
|
||||
|
@ -1594,56 +1593,55 @@ pub fn queue_shadows<M: Material>(
|
|||
// NOTE: Lights with shadow mapping disabled will have no visible entities
|
||||
// so no meshes will be queued
|
||||
for entity in visible_entities.iter().copied() {
|
||||
if let Ok((mesh_handle, material_handle)) = casting_meshes.get(entity) {
|
||||
if let (Some(mesh), Some(material)) = (
|
||||
render_meshes.get(mesh_handle),
|
||||
render_materials.get(&material_handle.id()),
|
||||
) {
|
||||
let mut mesh_key =
|
||||
MeshPipelineKey::from_primitive_topology(mesh.primitive_topology)
|
||||
| MeshPipelineKey::DEPTH_PREPASS;
|
||||
if mesh.morph_targets.is_some() {
|
||||
mesh_key |= MeshPipelineKey::MORPH_TARGETS;
|
||||
}
|
||||
if is_directional_light {
|
||||
mesh_key |= MeshPipelineKey::DEPTH_CLAMP_ORTHO;
|
||||
}
|
||||
let alpha_mode = material.properties.alpha_mode;
|
||||
match alpha_mode {
|
||||
AlphaMode::Mask(_)
|
||||
| AlphaMode::Blend
|
||||
| AlphaMode::Premultiplied
|
||||
| AlphaMode::Add => {
|
||||
mesh_key |= MeshPipelineKey::MAY_DISCARD;
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let pipeline_id = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&prepass_pipeline,
|
||||
MaterialPipelineKey {
|
||||
mesh_key,
|
||||
bind_group_data: material.key.clone(),
|
||||
},
|
||||
&mesh.layout,
|
||||
);
|
||||
|
||||
let pipeline_id = match pipeline_id {
|
||||
Ok(id) => id,
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
shadow_phase.add(Shadow {
|
||||
draw_function: draw_shadow_mesh,
|
||||
pipeline: pipeline_id,
|
||||
entity,
|
||||
distance: 0.0, // TODO: sort front-to-back
|
||||
});
|
||||
}
|
||||
let Ok((mesh_handle, material_handle)) = casting_meshes.get(entity) else {
|
||||
continue;
|
||||
};
|
||||
let Some(mesh) = render_meshes.get(mesh_handle) else {
|
||||
continue;
|
||||
};
|
||||
let Some(material) = render_materials.get(&material_handle.id()) else {
|
||||
continue;
|
||||
};
|
||||
let mut mesh_key =
|
||||
MeshPipelineKey::from_primitive_topology(mesh.primitive_topology)
|
||||
| MeshPipelineKey::DEPTH_PREPASS;
|
||||
if mesh.morph_targets.is_some() {
|
||||
mesh_key |= MeshPipelineKey::MORPH_TARGETS;
|
||||
}
|
||||
if is_directional_light {
|
||||
mesh_key |= MeshPipelineKey::DEPTH_CLAMP_ORTHO;
|
||||
}
|
||||
mesh_key |= match material.properties.alpha_mode {
|
||||
AlphaMode::Mask(_)
|
||||
| AlphaMode::Blend
|
||||
| AlphaMode::Premultiplied
|
||||
| AlphaMode::Add => MeshPipelineKey::MAY_DISCARD,
|
||||
_ => MeshPipelineKey::NONE,
|
||||
};
|
||||
let pipeline_id = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&prepass_pipeline,
|
||||
MaterialPipelineKey {
|
||||
mesh_key,
|
||||
bind_group_data: material.key.clone(),
|
||||
},
|
||||
&mesh.layout,
|
||||
);
|
||||
|
||||
let pipeline_id = match pipeline_id {
|
||||
Ok(id) => id,
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
shadow_phase.add(Shadow {
|
||||
draw_function: draw_shadow_mesh,
|
||||
pipeline: pipeline_id,
|
||||
entity,
|
||||
distance: 0.0, // TODO: sort front-to-back
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -127,37 +127,34 @@ fn queue_wireframes(
|
|||
let rangefinder = view.rangefinder3d();
|
||||
|
||||
let view_key = msaa_key | MeshPipelineKey::from_hdr(view.hdr);
|
||||
let add_render_phase =
|
||||
|(entity, mesh_handle, mesh_transforms): (Entity, &Handle<Mesh>, &MeshTransforms)| {
|
||||
if let Some(mesh) = render_meshes.get(mesh_handle) {
|
||||
let mut key = view_key
|
||||
| MeshPipelineKey::from_primitive_topology(mesh.primitive_topology);
|
||||
if mesh.morph_targets.is_some() {
|
||||
key |= MeshPipelineKey::MORPH_TARGETS;
|
||||
}
|
||||
let pipeline_id = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&wireframe_pipeline,
|
||||
key,
|
||||
&mesh.layout,
|
||||
);
|
||||
let pipeline_id = match pipeline_id {
|
||||
Ok(id) => id,
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
opaque_phase.add(Opaque3d {
|
||||
entity,
|
||||
pipeline: pipeline_id,
|
||||
draw_function: draw_custom,
|
||||
distance: rangefinder
|
||||
.distance_translation(&mesh_transforms.transform.translation),
|
||||
batch_size: 1,
|
||||
});
|
||||
let add_render_phase = |phase_item: (Entity, &Handle<Mesh>, &MeshTransforms)| {
|
||||
let (entity, mesh_handle, mesh_transforms) = phase_item;
|
||||
|
||||
let Some(mesh) = render_meshes.get(mesh_handle) else {
|
||||
return;
|
||||
};
|
||||
let mut key =
|
||||
view_key | MeshPipelineKey::from_primitive_topology(mesh.primitive_topology);
|
||||
if mesh.morph_targets.is_some() {
|
||||
key |= MeshPipelineKey::MORPH_TARGETS;
|
||||
}
|
||||
let pipeline_id =
|
||||
pipelines.specialize(&pipeline_cache, &wireframe_pipeline, key, &mesh.layout);
|
||||
let pipeline_id = match pipeline_id {
|
||||
Ok(id) => id,
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
return;
|
||||
}
|
||||
};
|
||||
opaque_phase.add(Opaque3d {
|
||||
entity,
|
||||
pipeline: pipeline_id,
|
||||
draw_function: draw_custom,
|
||||
distance: rangefinder.distance_translation(&mesh_transforms.transform.translation),
|
||||
batch_size: 1,
|
||||
});
|
||||
};
|
||||
|
||||
if wireframe_config.global {
|
||||
let query = material_meshes.p0();
|
||||
|
|
|
@ -319,6 +319,21 @@ impl<P: PhaseItem, M: Material2d, const I: usize> RenderCommand<P>
|
|||
}
|
||||
}
|
||||
|
||||
const fn tonemapping_pipeline_key(tonemapping: Tonemapping) -> Mesh2dPipelineKey {
|
||||
match tonemapping {
|
||||
Tonemapping::None => Mesh2dPipelineKey::TONEMAP_METHOD_NONE,
|
||||
Tonemapping::Reinhard => Mesh2dPipelineKey::TONEMAP_METHOD_REINHARD,
|
||||
Tonemapping::ReinhardLuminance => Mesh2dPipelineKey::TONEMAP_METHOD_REINHARD_LUMINANCE,
|
||||
Tonemapping::AcesFitted => Mesh2dPipelineKey::TONEMAP_METHOD_ACES_FITTED,
|
||||
Tonemapping::AgX => Mesh2dPipelineKey::TONEMAP_METHOD_AGX,
|
||||
Tonemapping::SomewhatBoringDisplayTransform => {
|
||||
Mesh2dPipelineKey::TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM
|
||||
}
|
||||
Tonemapping::TonyMcMapface => Mesh2dPipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE,
|
||||
Tonemapping::BlenderFilmic => Mesh2dPipelineKey::TONEMAP_METHOD_BLENDER_FILMIC,
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn queue_material2d_meshes<M: Material2d>(
|
||||
transparent_draw_functions: Res<DrawFunctions<Transparent2d>>,
|
||||
|
@ -352,69 +367,58 @@ pub fn queue_material2d_meshes<M: Material2d>(
|
|||
if !view.hdr {
|
||||
if let Some(tonemapping) = tonemapping {
|
||||
view_key |= Mesh2dPipelineKey::TONEMAP_IN_SHADER;
|
||||
view_key |= match tonemapping {
|
||||
Tonemapping::None => Mesh2dPipelineKey::TONEMAP_METHOD_NONE,
|
||||
Tonemapping::Reinhard => Mesh2dPipelineKey::TONEMAP_METHOD_REINHARD,
|
||||
Tonemapping::ReinhardLuminance => {
|
||||
Mesh2dPipelineKey::TONEMAP_METHOD_REINHARD_LUMINANCE
|
||||
}
|
||||
Tonemapping::AcesFitted => Mesh2dPipelineKey::TONEMAP_METHOD_ACES_FITTED,
|
||||
Tonemapping::AgX => Mesh2dPipelineKey::TONEMAP_METHOD_AGX,
|
||||
Tonemapping::SomewhatBoringDisplayTransform => {
|
||||
Mesh2dPipelineKey::TONEMAP_METHOD_SOMEWHAT_BORING_DISPLAY_TRANSFORM
|
||||
}
|
||||
Tonemapping::TonyMcMapface => Mesh2dPipelineKey::TONEMAP_METHOD_TONY_MC_MAPFACE,
|
||||
Tonemapping::BlenderFilmic => Mesh2dPipelineKey::TONEMAP_METHOD_BLENDER_FILMIC,
|
||||
};
|
||||
view_key |= tonemapping_pipeline_key(*tonemapping);
|
||||
}
|
||||
if let Some(DebandDither::Enabled) = dither {
|
||||
view_key |= Mesh2dPipelineKey::DEBAND_DITHER;
|
||||
}
|
||||
}
|
||||
|
||||
for visible_entity in &visible_entities.entities {
|
||||
if let Ok((material2d_handle, mesh2d_handle, mesh2d_uniform)) =
|
||||
let Ok((material2d_handle, mesh2d_handle, mesh2d_uniform)) =
|
||||
material2d_meshes.get(*visible_entity)
|
||||
{
|
||||
if let Some(material2d) = render_materials.get(&material2d_handle.id()) {
|
||||
if let Some(mesh) = render_meshes.get(&mesh2d_handle.0) {
|
||||
let mesh_key = view_key
|
||||
| Mesh2dPipelineKey::from_primitive_topology(mesh.primitive_topology);
|
||||
else {
|
||||
continue;
|
||||
};
|
||||
let Some(material2d) = render_materials.get(&material2d_handle.id()) else {
|
||||
continue;
|
||||
};
|
||||
let Some(mesh) = render_meshes.get(&mesh2d_handle.0) else {
|
||||
continue;
|
||||
};
|
||||
let mesh_key =
|
||||
view_key | Mesh2dPipelineKey::from_primitive_topology(mesh.primitive_topology);
|
||||
|
||||
let pipeline_id = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&material2d_pipeline,
|
||||
Material2dKey {
|
||||
mesh_key,
|
||||
bind_group_data: material2d.key.clone(),
|
||||
},
|
||||
&mesh.layout,
|
||||
);
|
||||
let pipeline_id = pipelines.specialize(
|
||||
&pipeline_cache,
|
||||
&material2d_pipeline,
|
||||
Material2dKey {
|
||||
mesh_key,
|
||||
bind_group_data: material2d.key.clone(),
|
||||
},
|
||||
&mesh.layout,
|
||||
);
|
||||
|
||||
let pipeline_id = match pipeline_id {
|
||||
Ok(id) => id,
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
|
||||
let mesh_z = mesh2d_uniform.transform.w_axis.z;
|
||||
transparent_phase.add(Transparent2d {
|
||||
entity: *visible_entity,
|
||||
draw_function: draw_transparent_pbr,
|
||||
pipeline: pipeline_id,
|
||||
// NOTE: Back-to-front ordering for transparent with ascending sort means far should have the
|
||||
// lowest sort key and getting closer should increase. As we have
|
||||
// -z in front of the camera, the largest distance is -far with values increasing toward the
|
||||
// camera. As such we can just use mesh_z as the distance
|
||||
sort_key: FloatOrd(mesh_z),
|
||||
// This material is not batched
|
||||
batch_size: 1,
|
||||
});
|
||||
}
|
||||
let pipeline_id = match pipeline_id {
|
||||
Ok(id) => id,
|
||||
Err(err) => {
|
||||
error!("{}", err);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let mesh_z = mesh2d_uniform.transform.w_axis.z;
|
||||
transparent_phase.add(Transparent2d {
|
||||
entity: *visible_entity,
|
||||
draw_function: draw_transparent_pbr,
|
||||
pipeline: pipeline_id,
|
||||
// NOTE: Back-to-front ordering for transparent with ascending sort means far should have the
|
||||
// lowest sort key and getting closer should increase. As we have
|
||||
// -z in front of the camera, the largest distance is -far with values increasing toward the
|
||||
// camera. As such we can just use mesh_z as the distance
|
||||
sort_key: FloatOrd(mesh_z),
|
||||
// This material is not batched
|
||||
batch_size: 1,
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue