2021-12-14 03:58:23 +00:00
|
|
|
pub mod wireframe;
|
2020-04-25 00:46:54 +00:00
|
|
|
|
2021-12-14 03:58:23 +00:00
|
|
|
mod alpha;
|
|
|
|
mod bundle;
|
2020-08-09 23:13:04 +00:00
|
|
|
mod light;
|
|
|
|
mod material;
|
2021-12-25 21:45:43 +00:00
|
|
|
mod pbr_material;
|
2021-12-14 03:58:23 +00:00
|
|
|
mod render;
|
2020-08-09 23:13:04 +00:00
|
|
|
|
2021-12-14 03:58:23 +00:00
|
|
|
pub use alpha::*;
|
|
|
|
pub use bundle::*;
|
2020-08-09 23:13:04 +00:00
|
|
|
pub use light::*;
|
|
|
|
pub use material::*;
|
2021-12-25 21:45:43 +00:00
|
|
|
pub use pbr_material::*;
|
2021-12-14 03:58:23 +00:00
|
|
|
pub use render::*;
|
2020-08-09 23:13:04 +00:00
|
|
|
|
2020-07-17 02:27:19 +00:00
|
|
|
pub mod prelude {
|
2021-04-27 18:29:33 +00:00
|
|
|
#[doc(hidden)]
|
2021-05-14 20:37:34 +00:00
|
|
|
pub use crate::{
|
2021-12-14 03:58:23 +00:00
|
|
|
alpha::AlphaMode,
|
2021-12-25 21:45:43 +00:00
|
|
|
bundle::{DirectionalLightBundle, MaterialMeshBundle, PbrBundle, PointLightBundle},
|
2021-12-14 03:58:23 +00:00
|
|
|
light::{AmbientLight, DirectionalLight, PointLight},
|
2021-12-25 21:45:43 +00:00
|
|
|
material::{Material, MaterialPlugin},
|
|
|
|
pbr_material::StandardMaterial,
|
2021-05-14 20:37:34 +00:00
|
|
|
};
|
2020-07-17 02:27:19 +00:00
|
|
|
}
|
2020-04-25 00:46:54 +00:00
|
|
|
|
2021-12-14 03:58:23 +00:00
|
|
|
pub mod draw_3d_graph {
|
|
|
|
pub mod node {
|
|
|
|
/// Label for the shadow pass node.
|
|
|
|
pub const SHADOW_PASS: &str = "shadow_pass";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-17 01:47:51 +00:00
|
|
|
use bevy_app::prelude::*;
|
2021-12-14 03:58:23 +00:00
|
|
|
use bevy_asset::{Assets, Handle, HandleUntyped};
|
|
|
|
use bevy_ecs::prelude::*;
|
|
|
|
use bevy_reflect::TypeUuid;
|
|
|
|
use bevy_render::{
|
2021-12-14 23:04:26 +00:00
|
|
|
prelude::Color,
|
2021-12-14 03:58:23 +00:00
|
|
|
render_graph::RenderGraph,
|
|
|
|
render_phase::{sort_phase_system, AddRenderCommand, DrawFunctions},
|
|
|
|
render_resource::{Shader, SpecializedPipelines},
|
|
|
|
view::VisibilitySystems,
|
|
|
|
RenderApp, RenderStage,
|
|
|
|
};
|
|
|
|
use bevy_transform::TransformSystem;
|
2020-04-25 00:46:54 +00:00
|
|
|
|
2021-12-14 03:58:23 +00:00
|
|
|
pub const PBR_SHADER_HANDLE: HandleUntyped =
|
|
|
|
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 4805239651767701046);
|
|
|
|
pub const SHADOW_SHADER_HANDLE: HandleUntyped =
|
|
|
|
HandleUntyped::weak_from_u64(Shader::TYPE_UUID, 1836745567947005696);
|
|
|
|
|
|
|
|
/// Sets up the entire PBR infrastructure of bevy.
|
2020-04-25 00:46:54 +00:00
|
|
|
#[derive(Default)]
|
|
|
|
pub struct PbrPlugin;
|
|
|
|
|
2020-08-08 03:22:17 +00:00
|
|
|
impl Plugin for PbrPlugin {
|
2021-07-27 20:21:06 +00:00
|
|
|
fn build(&self, app: &mut App) {
|
2021-12-14 03:58:23 +00:00
|
|
|
let mut shaders = app.world.get_resource_mut::<Assets<Shader>>().unwrap();
|
|
|
|
shaders.set_untracked(
|
|
|
|
PBR_SHADER_HANDLE,
|
|
|
|
Shader::from_wgsl(include_str!("render/pbr.wgsl")),
|
|
|
|
);
|
|
|
|
shaders.set_untracked(
|
|
|
|
SHADOW_SHADER_HANDLE,
|
|
|
|
Shader::from_wgsl(include_str!("render/depth.wgsl")),
|
|
|
|
);
|
|
|
|
|
2021-12-25 21:45:43 +00:00
|
|
|
app.add_plugin(MeshRenderPlugin)
|
|
|
|
.add_plugin(MaterialPlugin::<StandardMaterial>::default())
|
2021-12-14 03:58:23 +00:00
|
|
|
.init_resource::<AmbientLight>()
|
|
|
|
.init_resource::<DirectionalLightShadowMap>()
|
|
|
|
.init_resource::<PointLightShadowMap>()
|
|
|
|
.init_resource::<AmbientLight>()
|
|
|
|
.init_resource::<VisiblePointLights>()
|
|
|
|
.add_system_to_stage(
|
|
|
|
CoreStage::PostUpdate,
|
|
|
|
// NOTE: Clusters need to have been added before update_clusters is run so
|
|
|
|
// add as an exclusive system
|
|
|
|
add_clusters
|
|
|
|
.exclusive_system()
|
|
|
|
.label(SimulationLightSystems::AddClusters),
|
|
|
|
)
|
|
|
|
.add_system_to_stage(
|
|
|
|
CoreStage::PostUpdate,
|
|
|
|
// NOTE: Must come after add_clusters!
|
|
|
|
update_clusters
|
|
|
|
.label(SimulationLightSystems::UpdateClusters)
|
|
|
|
.after(TransformSystem::TransformPropagate),
|
|
|
|
)
|
|
|
|
.add_system_to_stage(
|
|
|
|
CoreStage::PostUpdate,
|
|
|
|
assign_lights_to_clusters
|
|
|
|
.label(SimulationLightSystems::AssignLightsToClusters)
|
|
|
|
.after(TransformSystem::TransformPropagate)
|
|
|
|
.after(SimulationLightSystems::UpdateClusters),
|
|
|
|
)
|
|
|
|
.add_system_to_stage(
|
|
|
|
CoreStage::PostUpdate,
|
|
|
|
update_directional_light_frusta
|
|
|
|
.label(SimulationLightSystems::UpdateDirectionalLightFrusta)
|
|
|
|
.after(TransformSystem::TransformPropagate),
|
|
|
|
)
|
2020-05-26 04:57:48 +00:00
|
|
|
.add_system_to_stage(
|
2021-02-18 21:20:37 +00:00
|
|
|
CoreStage::PostUpdate,
|
2021-12-14 03:58:23 +00:00
|
|
|
update_point_light_frusta
|
|
|
|
.label(SimulationLightSystems::UpdatePointLightFrusta)
|
|
|
|
.after(TransformSystem::TransformPropagate)
|
|
|
|
.after(SimulationLightSystems::AssignLightsToClusters),
|
2020-11-15 19:34:55 +00:00
|
|
|
)
|
2021-12-14 03:58:23 +00:00
|
|
|
.add_system_to_stage(
|
|
|
|
CoreStage::PostUpdate,
|
|
|
|
check_light_mesh_visibility
|
|
|
|
.label(SimulationLightSystems::CheckLightVisibility)
|
|
|
|
.after(TransformSystem::TransformPropagate)
|
|
|
|
.after(VisibilitySystems::CalculateBounds)
|
|
|
|
.after(SimulationLightSystems::UpdateDirectionalLightFrusta)
|
|
|
|
.after(SimulationLightSystems::UpdatePointLightFrusta)
|
|
|
|
// NOTE: This MUST be scheduled AFTER the core renderer visibility check
|
|
|
|
// because that resets entity ComputedVisibility for the first view
|
|
|
|
// which would override any results from this otherwise
|
|
|
|
.after(VisibilitySystems::CheckVisibility),
|
|
|
|
);
|
|
|
|
|
2021-12-14 23:04:26 +00:00
|
|
|
app.world
|
|
|
|
.get_resource_mut::<Assets<StandardMaterial>>()
|
|
|
|
.unwrap()
|
|
|
|
.set_untracked(
|
2021-12-25 21:45:43 +00:00
|
|
|
Handle::<StandardMaterial>::default(),
|
2021-12-14 23:04:26 +00:00
|
|
|
StandardMaterial {
|
|
|
|
base_color: Color::rgb(1.0, 0.0, 0.5),
|
|
|
|
unlit: true,
|
|
|
|
..Default::default()
|
|
|
|
},
|
|
|
|
);
|
|
|
|
|
2021-12-24 06:57:30 +00:00
|
|
|
let render_app = app.sub_app_mut(RenderApp);
|
2021-12-14 03:58:23 +00:00
|
|
|
render_app
|
|
|
|
.add_system_to_stage(
|
|
|
|
RenderStage::Extract,
|
|
|
|
render::extract_clusters.label(RenderLightSystems::ExtractClusters),
|
|
|
|
)
|
|
|
|
.add_system_to_stage(
|
|
|
|
RenderStage::Extract,
|
|
|
|
render::extract_lights.label(RenderLightSystems::ExtractLights),
|
|
|
|
)
|
|
|
|
.add_system_to_stage(
|
|
|
|
RenderStage::Prepare,
|
|
|
|
// this is added as an exclusive system because it contributes new views. it must run (and have Commands applied)
|
|
|
|
// _before_ the `prepare_views()` system is run. ideally this becomes a normal system when "stageless" features come out
|
|
|
|
render::prepare_lights
|
|
|
|
.exclusive_system()
|
|
|
|
.label(RenderLightSystems::PrepareLights),
|
|
|
|
)
|
|
|
|
.add_system_to_stage(
|
|
|
|
RenderStage::Prepare,
|
|
|
|
// this is added as an exclusive system because it contributes new views. it must run (and have Commands applied)
|
|
|
|
// _before_ the `prepare_views()` system is run. ideally this becomes a normal system when "stageless" features come out
|
|
|
|
render::prepare_clusters
|
|
|
|
.exclusive_system()
|
|
|
|
.label(RenderLightSystems::PrepareClusters)
|
|
|
|
.after(RenderLightSystems::PrepareLights),
|
|
|
|
)
|
|
|
|
.add_system_to_stage(
|
|
|
|
RenderStage::Queue,
|
|
|
|
render::queue_shadows.label(RenderLightSystems::QueueShadows),
|
|
|
|
)
|
|
|
|
.add_system_to_stage(RenderStage::Queue, render::queue_shadow_view_bind_group)
|
|
|
|
.add_system_to_stage(RenderStage::PhaseSort, sort_phase_system::<Shadow>)
|
|
|
|
.init_resource::<ShadowPipeline>()
|
|
|
|
.init_resource::<DrawFunctions<Shadow>>()
|
|
|
|
.init_resource::<LightMeta>()
|
|
|
|
.init_resource::<GlobalLightMeta>()
|
|
|
|
.init_resource::<SpecializedPipelines<ShadowPipeline>>();
|
2020-10-18 20:48:15 +00:00
|
|
|
|
2021-12-14 03:58:23 +00:00
|
|
|
let shadow_pass_node = ShadowPassNode::new(&mut render_app.world);
|
|
|
|
render_app.add_render_command::<Shadow, DrawShadowMesh>();
|
|
|
|
let mut graph = render_app.world.get_resource_mut::<RenderGraph>().unwrap();
|
|
|
|
let draw_3d_graph = graph
|
|
|
|
.get_sub_graph_mut(bevy_core_pipeline::draw_3d_graph::NAME)
|
|
|
|
.unwrap();
|
|
|
|
draw_3d_graph.add_node(draw_3d_graph::node::SHADOW_PASS, shadow_pass_node);
|
|
|
|
draw_3d_graph
|
|
|
|
.add_node_edge(
|
|
|
|
draw_3d_graph::node::SHADOW_PASS,
|
|
|
|
bevy_core_pipeline::draw_3d_graph::node::MAIN_PASS,
|
|
|
|
)
|
|
|
|
.unwrap();
|
|
|
|
draw_3d_graph
|
|
|
|
.add_slot_edge(
|
|
|
|
draw_3d_graph.input_node().unwrap().id,
|
|
|
|
bevy_core_pipeline::draw_3d_graph::input::VIEW_ENTITY,
|
|
|
|
draw_3d_graph::node::SHADOW_PASS,
|
|
|
|
ShadowPassNode::IN_VIEW,
|
|
|
|
)
|
2020-10-18 20:48:15 +00:00
|
|
|
.unwrap();
|
2020-04-25 00:46:54 +00:00
|
|
|
}
|
|
|
|
}
|