Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Use prepass shaders for shadows #7784

Closed
wants to merge 8 commits into from
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
15 changes: 13 additions & 2 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,10 @@ 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)
// 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)
|| key.mesh_key.contains(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