use bevy::{
app::{App, Plugin},
asset::embedded_asset,
core_pipeline::core_2d::graph::Core2d,
ecs::schedule::IntoScheduleConfigs as _,
render::{
ExtractSchedule, Render, RenderApp, RenderDebugFlags, RenderStartup, RenderSystems,
batching::no_gpu_preprocessing::batch_and_prepare_sorted_render_phase,
extract_component::UniformComponentPlugin,
extract_resource::ExtractResourcePlugin,
render_graph::{RenderGraphExt, RenderLabel, ViewNodeRunner},
render_phase::{
AddRenderCommand as _, DrawFunctions, SortedRenderPhasePlugin, ViewSortedRenderPhases,
sort_phase_system,
},
render_resource::SpecializedMeshPipelines,
},
shader::load_shader_library,
sprite_render::{Mesh2dPipeline, init_mesh_2d_pipeline},
};
use crate::{light::prelude::*, plugin::prelude::*};
pub(crate) struct Light2dPlugin;
impl Plugin for Light2dPlugin {
fn build(&self, app: &mut App) {
load_shader_library!(app, "types.wgsl");
embedded_asset!(app, "light_2d.wgsl");
embedded_asset!(app, "light_2d_composite.wgsl");
app.add_plugins((
SortedRenderPhasePlugin::<Light2dPhase, Mesh2dPipeline>::new(
RenderDebugFlags::default(),
),
ExtractResourcePlugin::<FastLightSettings>::default(),
UniformComponentPlugin::<ExtractedAmbientLight2d>::default(),
));
let Some(render_app) = app.get_sub_app_mut(RenderApp) else {
return;
};
render_app
.init_resource::<DrawFunctions<Light2dPhase>>()
.init_resource::<SpecializedMeshPipelines<Light2dPipeline>>()
.init_resource::<ViewSortedRenderPhases<Light2dPhase>>()
.init_resource::<Light2dTextures>()
.init_resource::<Light2dFragmentBindGroups>()
.init_resource::<Light2dUniformBuffers>();
render_app.add_render_command::<Light2dPhase, DrawLight2d>();
render_app.add_systems(
RenderStartup,
(
super::pipeline::init_light_2d_pipeline.after(init_mesh_2d_pipeline),
super::pipeline::init_light_2d_composite_pipeline,
),
);
render_app.add_systems(
ExtractSchedule,
(
super::extract::extract_light_2d_view_entities,
super::extract::extract_ambient_light,
super::extract::extract_mesh_lights,
),
);
render_app.add_systems(
Render,
(
super::phase::queue_light_2ds.in_set(RenderSystems::Queue),
sort_phase_system::<Light2dPhase>.in_set(RenderSystems::PhaseSort),
(
batch_and_prepare_sorted_render_phase::<Light2dPhase, Light2dPipeline>,
super::prepare::prepare_light_2d_texture,
(
super::prepare::prepare_light_2d_buffers,
super::prepare::prepare_light_2d_fragment_bind_groups,
)
.chain(),
)
.in_set(RenderSystems::PrepareResources),
),
);
render_app
.add_render_graph_node::<ViewNodeRunner<Light2dNode>>(Core2d, Light2dLabel)
.add_render_graph_node::<ViewNodeRunner<Light2dCompositeNode>>(
Core2d,
Light2dCompositeLabel,
);
}
}
#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)]
pub(crate) struct Light2dLabel;
#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)]
pub(crate) struct Light2dCompositeLabel;