use bevy::core_pipeline::FullscreenShader;
use bevy::image::BevyDefault;
use bevy::prelude::*;
use bevy::render::render_resource::binding_types::{sampler, texture_2d};
use bevy::render::render_resource::{
BindGroupLayoutDescriptor, BindGroupLayoutEntries, ColorTargetState, ColorWrites,
FragmentState, MultisampleState, PrimitiveState, RenderPipelineDescriptor, Sampler,
SamplerBindingType, SamplerDescriptor, ShaderStages, SpecializedRenderPipeline, TextureFormat,
TextureSampleType,
};
use bevy::render::renderer::RenderDevice;
use bevy::render::view::ViewTarget;
use super::{LIGHTING_SHADER, LightingPipelineKey};
const LIGHTING_PIPELINE: &str = "lighting_pipeline";
const LIGHTING_BIND_GROUP_LAYOUT: &str = "lighting_bind_group_layout";
#[derive(Resource)]
pub struct LightingPipeline {
pub layout_descriptor: BindGroupLayoutDescriptor,
pub sampler: Sampler,
pub fullscreen_shader: FullscreenShader,
}
impl FromWorld for LightingPipeline {
fn from_world(world: &mut World) -> Self {
let render_device = world.resource::<RenderDevice>();
let layout_descriptor = BindGroupLayoutDescriptor::new(
LIGHTING_BIND_GROUP_LAYOUT,
&BindGroupLayoutEntries::sequential(
ShaderStages::FRAGMENT,
(
texture_2d(TextureSampleType::Float { filterable: true }),
texture_2d(TextureSampleType::Float { filterable: true }),
sampler(SamplerBindingType::Filtering),
),
),
);
let sampler = render_device.create_sampler(&SamplerDescriptor::default());
let fullscreen_shader = world.resource::<FullscreenShader>().clone();
Self {
layout_descriptor,
sampler,
fullscreen_shader,
}
}
}
impl SpecializedRenderPipeline for LightingPipeline {
type Key = LightingPipelineKey;
fn specialize(&self, key: Self::Key) -> RenderPipelineDescriptor {
RenderPipelineDescriptor {
label: Some(LIGHTING_PIPELINE.into()),
layout: vec![self.layout_descriptor.clone()],
vertex: self.fullscreen_shader.to_vertex_state(),
fragment: Some(FragmentState {
shader: LIGHTING_SHADER,
shader_defs: vec![],
entry_point: Some("fragment".into()),
targets: vec![Some(ColorTargetState {
format: if key.hdr {
ViewTarget::TEXTURE_FORMAT_HDR
} else {
TextureFormat::bevy_default()
},
blend: None,
write_mask: ColorWrites::ALL,
})],
}),
primitive: PrimitiveState::default(),
depth_stencil: None,
multisample: MultisampleState::default(),
push_constant_ranges: vec![],
zero_initialize_workgroup_memory: false,
}
}
}