Skip to content

Commit

Permalink
Use prepass shaders for shadows (#7784)
Browse files Browse the repository at this point in the history
# Objective

- Fixes #4372.

## Solution

- Use the prepass shaders for the shadow passes.
- Move `DEPTH_CLAMP_ORTHO` from `ShadowPipelineKey` to `MeshPipelineKey` and the associated clamp operation from `depth.wgsl` to `prepass.wgsl`.
- Remove `depth.wgsl` .
- Replace `ShadowPipeline` with `ShadowSamplers`.

Instead of running the custom `ShadowPipeline` we run the `PrepassPipeline` with the `DEPTH_PREPASS` flag and additionally the `DEPTH_CLAMP_ORTHO` flag for directional lights as well as the `ALPHA_MASK` flag for materials that use `AlphaMode::Mask(_)`.
  • Loading branch information
geieredgar committed Mar 2, 2023
1 parent a39c223 commit e54103f
Show file tree
Hide file tree
Showing 8 changed files with 125 additions and 260 deletions.
21 changes: 4 additions & 17 deletions crates/bevy_pbr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ use bevy_render::{
extract_resource::ExtractResourcePlugin,
prelude::Color,
render_graph::RenderGraph,
render_phase::{sort_phase_system, AddRenderCommand, DrawFunctions},
render_resource::{Shader, SpecializedMeshPipelines},
render_phase::sort_phase_system,
render_resource::Shader,
view::{ViewSet, VisibilitySystems},
ExtractSchedule, RenderApp, RenderSet,
};
Expand All @@ -80,8 +80,6 @@ pub const PBR_FUNCTIONS_HANDLE: HandleUntyped =
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 16550102964439850292);
pub const PBR_AMBIENT_HANDLE: HandleUntyped =
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 2441520459096337034);
pub const SHADOW_SHADER_HANDLE: HandleUntyped =
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 1836745567947005696);

/// Sets up the entire PBR infrastructure of bevy.
pub struct PbrPlugin {
Expand Down Expand Up @@ -144,12 +142,6 @@ impl Plugin for PbrPlugin {
Shader::from_wgsl
);
load_internal_asset!(app, PBR_SHADER_HANDLE, "render/pbr.wgsl", Shader::from_wgsl);
load_internal_asset!(
app,
SHADOW_SHADER_HANDLE,
"render/depth.wgsl",
Shader::from_wgsl
);
load_internal_asset!(
app,
PBR_PREPASS_SHADER_HANDLE,
Expand Down Expand Up @@ -293,17 +285,12 @@ impl Plugin for PbrPlugin {
.after(render::prepare_lights)
.in_set(RenderLightSystems::PrepareClusters),
)
.add_system(render::queue_shadows.in_set(RenderLightSystems::QueueShadows))
.add_system(render::queue_shadow_view_bind_group.in_set(RenderSet::Queue))
.add_system(sort_phase_system::<Shadow>.in_set(RenderSet::PhaseSort))
.init_resource::<ShadowPipeline>()
.init_resource::<DrawFunctions<Shadow>>()
.init_resource::<ShadowSamplers>()
.init_resource::<LightMeta>()
.init_resource::<GlobalLightMeta>()
.init_resource::<SpecializedMeshPipelines<ShadowPipeline>>();
.init_resource::<GlobalLightMeta>();

let shadow_pass_node = ShadowPassNode::new(&mut render_app.world);
render_app.add_render_command::<Shadow, DrawShadowMesh>();
let mut graph = render_app.world.resource_mut::<RenderGraph>();
let draw_3d_graph = graph
.get_sub_graph_mut(bevy_core_pipeline::core_3d::graph::NAME)
Expand Down
13 changes: 11 additions & 2 deletions crates/bevy_pbr/src/material.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use crate::{
AlphaMode, DrawMesh, EnvironmentMapLight, MeshPipeline, MeshPipelineKey, MeshUniform,
PrepassPlugin, SetMeshBindGroup, SetMeshViewBindGroup,
queue_mesh_view_bind_groups, render, AlphaMode, DrawMesh, DrawPrepass, EnvironmentMapLight,
MeshPipeline, MeshPipelineKey, MeshUniform, PrepassPlugin, RenderLightSystems,
SetMeshBindGroup, SetMeshViewBindGroup, Shadow,
};
use bevy_app::{App, IntoSystemAppConfig, Plugin};
use bevy_asset::{AddAsset, AssetEvent, AssetServer, Assets, Handle};
Expand Down Expand Up @@ -188,6 +189,8 @@ where

if let Ok(render_app) = app.get_sub_app_mut(RenderApp) {
render_app
.init_resource::<DrawFunctions<Shadow>>()
.add_render_command::<Shadow, DrawPrepass<M>>()
.add_render_command::<Transparent3d, DrawMaterial<M>>()
.add_render_command::<Opaque3d, DrawMaterial<M>>()
.add_render_command::<AlphaMask3d, DrawMaterial<M>>()
Expand All @@ -201,6 +204,12 @@ where
.in_set(RenderSet::Prepare)
.after(PrepareAssetSet::PreAssetPrepare),
)
.add_system(render::queue_shadows::<M>.in_set(RenderLightSystems::QueueShadows))
.add_system(
render::queue_shadow_view_bind_group::<M>
.in_set(RenderSet::Queue)
.ambiguous_with(queue_mesh_view_bind_groups), // queue_mesh_view_bind_groups does not read `shadow_view_bind_group`),
)
.add_system(queue_material_meshes::<M>.in_set(RenderSet::Queue));
}

Expand Down
18 changes: 15 additions & 3 deletions crates/bevy_pbr/src/prepass/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,13 @@ where
shader_defs.push("ALPHA_MASK".into());
}

let blend_key = key
.mesh_key
.intersection(MeshPipelineKey::BLEND_RESERVED_BITS);
if blend_key == MeshPipelineKey::BLEND_PREMULTIPLIED_ALPHA {
shader_defs.push("BLEND_PREMULTIPLIED_ALPHA".into());
}

if layout.contains(Mesh::ATTRIBUTE_POSITION) {
shader_defs.push("VERTEX_POSITIONS".into());
vertex_attributes.push(Mesh::ATTRIBUTE_POSITION.at_shader_location(0));
Expand All @@ -215,6 +222,9 @@ where
"MAX_CASCADES_PER_LIGHT".to_string(),
MAX_CASCADES_PER_LIGHT as i32,
));
if key.mesh_key.contains(MeshPipelineKey::DEPTH_CLAMP_ORTHO) {
shader_defs.push("DEPTH_CLAMP_ORTHO".into());
}

if layout.contains(Mesh::ATTRIBUTE_UV_0) {
shader_defs.push("VERTEX_UVS".into());
Expand Down Expand Up @@ -244,9 +254,11 @@ where

let vertex_buffer_layout = layout.get_layout(&vertex_attributes)?;

// The fragment shader is only used when the normal prepass is enabled or the material uses an alpha mask
let fragment = if key.mesh_key.contains(MeshPipelineKey::NORMAL_PREPASS)
|| key.mesh_key.contains(MeshPipelineKey::ALPHA_MASK)
// The fragment shader is only used when the normal prepass is enabled or the material uses alpha cutoff values
let fragment = if key
.mesh_key
.intersects(MeshPipelineKey::NORMAL_PREPASS | MeshPipelineKey::ALPHA_MASK)
|| blend_key == MeshPipelineKey::BLEND_PREMULTIPLIED_ALPHA
{
// Use the fragment shader from the material if present
let frag_shader_handle = if let Some(handle) = &self.material_fragment_shader {
Expand Down
3 changes: 3 additions & 0 deletions crates/bevy_pbr/src/prepass/prepass.wgsl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ fn vertex(vertex: Vertex) -> VertexOutput {
#endif // SKINNED

out.clip_position = mesh_position_local_to_clip(model, vec4(vertex.position, 1.0));
#ifdef DEPTH_CLAMP_ORTHO
out.clip_position.z = min(out.clip_position.z, 1.0);
#endif // DEPTH_CLAMP_ORTHO

#ifdef VERTEX_UVS
out.uv = vertex.uv;
Expand Down
46 changes: 0 additions & 46 deletions crates/bevy_pbr/src/render/depth.wgsl

This file was deleted.

Loading

0 comments on commit e54103f

Please sign in to comment.