Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions crates/bevy_pbr/src/material.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1876,3 +1876,19 @@ pub fn get_mesh_instance_world_from_local(
}
}
}

pub(crate) trait MaterialPropertiesExt {
fn prepass_reads_material(&self) -> bool;
}

impl MaterialPropertiesExt for MaterialProperties {
fn prepass_reads_material(&self) -> bool {
// The default prepass shaders doesn't need material's bind group,
// but for user provided prepass shaders currently we don't have a way to known this
// because material's bind group is used for both prepass and the other passes.
//
// So we have to disable the optimization for depth only prepass and always bind the material's bind group.
self.get_shader(PrepassVertexShader).is_some()
|| self.get_shader(PrepassFragmentShader).is_some()
}
}
26 changes: 19 additions & 7 deletions crates/bevy_pbr/src/prepass/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ use crate::{
alpha_mode_pipeline_key, binding_arrays_are_usable, buffer_layout,
collect_meshes_for_gpu_building, init_material_pipeline, set_mesh_motion_vector_flags,
setup_morph_and_skinning_defs, skin, DeferredAlphaMaskDrawFunction, DeferredFragmentShader,
DeferredOpaqueDrawFunction, DeferredVertexShader, DrawMesh, MaterialPipeline, MeshLayouts,
MeshPipeline, MeshPipelineKey, PreparedMaterial, PrepassAlphaMaskDrawFunction,
PrepassFragmentShader, PrepassOpaqueDepthOnlyDrawFunction, PrepassOpaqueDrawFunction,
PrepassVertexShader, RenderLightmaps, RenderMaterialInstances, RenderMeshInstanceFlags,
RenderMeshInstances, SetMaterialBindGroup, SetMeshBindGroup, ShadowView,
DeferredOpaqueDrawFunction, DeferredVertexShader, DrawMesh, MaterialPipeline,
MaterialPropertiesExt, MeshLayouts, MeshPipeline, MeshPipelineKey, PreparedMaterial,
PrepassAlphaMaskDrawFunction, PrepassFragmentShader, PrepassOpaqueDepthOnlyDrawFunction,
PrepassOpaqueDrawFunction, PrepassVertexShader, RenderLightmaps, RenderMaterialInstances,
RenderMeshInstanceFlags, RenderMeshInstances, SetMaterialBindGroup, SetMeshBindGroup,
ShadowView,
};
use bevy_app::{App, Plugin, PreUpdate};
use bevy_asset::{embedded_asset, load_embedded_asset, AssetServer, Handle};
Expand Down Expand Up @@ -390,7 +391,9 @@ impl SpecializedMeshPipeline for PrepassPipelineSpecializer {
}

fn is_depth_only_opaque_prepass(mesh_key: MeshPipelineKey) -> bool {
mesh_key.intersection(MeshPipelineKey::ALL_PREPASS_BITS) == MeshPipelineKey::DEPTH_PREPASS
!mesh_key.intersects(MeshPipelineKey::MAY_DISCARD | MeshPipelineKey::PREPASS_READS_MATERIAL)
&& mesh_key.intersection(MeshPipelineKey::ALL_PREPASS_BITS)
== MeshPipelineKey::DEPTH_PREPASS
}

impl PrepassPipeline {
Expand Down Expand Up @@ -425,7 +428,12 @@ impl PrepassPipeline {
// or emulated by setting depth in the fragment shader for GPUs that don't support it natively.
let emulate_unclipped_depth = mesh_key.contains(MeshPipelineKey::UNCLIPPED_DEPTH_ORTHO)
&& !self.depth_clip_control_supported;
if is_depth_only_opaque_prepass(mesh_key) && !emulate_unclipped_depth {
if is_depth_only_opaque_prepass(mesh_key)
&& !emulate_unclipped_depth
&& !material_properties.prepass_reads_material()
{
// The shaders for depth only opaque prepass doesn't need material's bind group.
// We set an empty layout and batch them by setting `material_bind_group_index` to `None` in batch set key.
bind_group_layouts.push(self.empty_layout.clone());
} else {
bind_group_layouts.push(
Expand Down Expand Up @@ -1181,6 +1189,10 @@ pub(crate) fn specialize_prepass_material_meshes(
mesh_key |= MeshPipelineKey::VISIBILITY_RANGE_DITHER;
}

if material.properties.prepass_reads_material() {
mesh_key |= MeshPipelineKey::PREPASS_READS_MATERIAL;
}

// If the previous frame has skins or morph targets, note that.
if motion_vector_prepass.is_some() {
if mesh_instance
Expand Down
4 changes: 4 additions & 0 deletions crates/bevy_pbr/src/render/light.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2448,6 +2448,10 @@ pub(crate) fn specialize_shadows(
_ => MeshPipelineKey::NONE,
};

if material.properties.prepass_reads_material() {
mesh_key |= MeshPipelineKey::PREPASS_READS_MATERIAL;
}

work_items.push(ShadowSpecializationWorkItem {
visible_entity: *visible_entity,
retained_view_entity: extracted_view_light.retained_view_entity,
Expand Down
Loading