Path: blob/main/crates/bevy_solari/src/realtime/prepare.rs
9419 views
use super::SolariLighting;1#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]2use bevy_anti_alias::dlss::{3Dlss, DlssRayReconstructionFeature, ViewDlssRayReconstructionTextures,4};5use bevy_camera::MainPassResolutionOverride;6#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]7use bevy_ecs::query::Has;8use bevy_ecs::{9component::Component,10entity::Entity,11query::With,12system::{Commands, Query, Res},13};14use bevy_image::ToExtents;15use bevy_math::UVec2;16#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]17use bevy_render::texture::CachedTexture;18use bevy_render::{19camera::ExtractedCamera,20render_resource::{21Buffer, BufferDescriptor, BufferUsages, TextureDescriptor, TextureDimension, TextureFormat,22TextureUsages, TextureView, TextureViewDescriptor,23},24renderer::RenderDevice,25};2627/// Size of the `LightSample` shader struct in bytes.28const LIGHT_SAMPLE_STRUCT_SIZE: u64 = 8;2930/// Size of the `ResolvedLightSamplePacked` shader struct in bytes.31const RESOLVED_LIGHT_SAMPLE_STRUCT_SIZE: u64 = 24;3233/// Size of the GI `Reservoir` shader struct in bytes.34const GI_RESERVOIR_STRUCT_SIZE: u64 = 48;3536pub const LIGHT_TILE_BLOCKS: u64 = 128;37pub const LIGHT_TILE_SAMPLES_PER_BLOCK: u64 = 1024;3839/// Amount of entries in the world cache (must be a power of 2, and >= 2^10)40pub const WORLD_CACHE_SIZE: u64 = 2u64.pow(20);4142/// Internal rendering resources used for Solari lighting.43#[derive(Component)]44pub struct SolariLightingResources {45pub light_tile_samples: Buffer,46pub light_tile_resolved_samples: Buffer,47pub di_reservoirs_a: TextureView,48pub di_reservoirs_b: TextureView,49pub gi_reservoirs_a: Buffer,50pub gi_reservoirs_b: Buffer,51pub world_cache_checksums: Buffer,52pub world_cache_life: Buffer,53pub world_cache_radiance: Buffer,54pub world_cache_geometry_data: Buffer,55pub world_cache_luminance_deltas: Buffer,56pub world_cache_active_cells_new_radiance: Buffer,57pub world_cache_a: Buffer,58pub world_cache_b: Buffer,59pub world_cache_active_cell_indices: Buffer,60pub world_cache_active_cells_count: Buffer,61pub world_cache_active_cells_dispatch: Buffer,62pub view_size: UVec2,63}6465pub fn prepare_solari_lighting_resources(66#[cfg(any(not(feature = "dlss"), feature = "force_disable_dlss"))] query: Query<67(68Entity,69&ExtractedCamera,70Option<&SolariLightingResources>,71Option<&MainPassResolutionOverride>,72),73With<SolariLighting>,74>,75#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))] query: Query<76(77Entity,78&ExtractedCamera,79Option<&SolariLightingResources>,80Option<&MainPassResolutionOverride>,81Has<Dlss<DlssRayReconstructionFeature>>,82),83With<SolariLighting>,84>,85render_device: Res<RenderDevice>,86mut commands: Commands,87) {88for query_item in &query {89#[cfg(any(not(feature = "dlss"), feature = "force_disable_dlss"))]90let (entity, camera, solari_lighting_resources, resolution_override) = query_item;91#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]92let (entity, camera, solari_lighting_resources, resolution_override, has_dlss_rr) =93query_item;9495let Some(mut view_size) = camera.physical_viewport_size else {96continue;97};98if let Some(MainPassResolutionOverride(resolution_override)) = resolution_override {99view_size = *resolution_override;100}101102if solari_lighting_resources.map(|r| r.view_size) == Some(view_size) {103continue;104}105106let light_tile_samples = render_device.create_buffer(&BufferDescriptor {107label: Some("solari_lighting_light_tile_samples"),108size: LIGHT_TILE_BLOCKS * LIGHT_TILE_SAMPLES_PER_BLOCK * LIGHT_SAMPLE_STRUCT_SIZE,109usage: BufferUsages::STORAGE,110mapped_at_creation: false,111});112113let light_tile_resolved_samples = render_device.create_buffer(&BufferDescriptor {114label: Some("solari_lighting_light_tile_resolved_samples"),115size: LIGHT_TILE_BLOCKS116* LIGHT_TILE_SAMPLES_PER_BLOCK117* RESOLVED_LIGHT_SAMPLE_STRUCT_SIZE,118usage: BufferUsages::STORAGE,119mapped_at_creation: false,120});121122let di_reservoirs = |name| {123render_device124.create_texture(&TextureDescriptor {125label: Some(name),126size: view_size.to_extents(),127mip_level_count: 1,128sample_count: 1,129dimension: TextureDimension::D2,130format: TextureFormat::Rgba32Uint,131usage: TextureUsages::STORAGE_BINDING,132view_formats: &[],133})134.create_view(&TextureViewDescriptor::default())135};136let di_reservoirs_a = di_reservoirs("solari_lighting_di_reservoirs_a");137let di_reservoirs_b = di_reservoirs("solari_lighting_di_reservoirs_b");138139let gi_reservoirs = |name| {140render_device.create_buffer(&BufferDescriptor {141label: Some(name),142size: (view_size.x * view_size.y) as u64 * GI_RESERVOIR_STRUCT_SIZE,143usage: BufferUsages::STORAGE,144mapped_at_creation: false,145})146};147let gi_reservoirs_a = gi_reservoirs("solari_lighting_gi_reservoirs_a");148let gi_reservoirs_b = gi_reservoirs("solari_lighting_gi_reservoirs_b");149150let world_cache_checksums = render_device.create_buffer(&BufferDescriptor {151label: Some("solari_lighting_world_cache_checksums"),152size: WORLD_CACHE_SIZE * size_of::<u32>() as u64,153usage: BufferUsages::STORAGE,154mapped_at_creation: false,155});156157let world_cache_life = render_device.create_buffer(&BufferDescriptor {158label: Some("solari_lighting_world_cache_life"),159size: WORLD_CACHE_SIZE * size_of::<u32>() as u64,160usage: BufferUsages::STORAGE,161mapped_at_creation: false,162});163164let world_cache_radiance = render_device.create_buffer(&BufferDescriptor {165label: Some("solari_lighting_world_cache_radiance"),166size: WORLD_CACHE_SIZE * size_of::<[f32; 4]>() as u64,167usage: BufferUsages::STORAGE,168mapped_at_creation: false,169});170171let world_cache_geometry_data = render_device.create_buffer(&BufferDescriptor {172label: Some("solari_lighting_world_cache_geometry_data"),173size: WORLD_CACHE_SIZE * size_of::<[f32; 8]>() as u64,174usage: BufferUsages::STORAGE,175mapped_at_creation: false,176});177178let world_cache_luminance_deltas = render_device.create_buffer(&BufferDescriptor {179label: Some("solari_lighting_world_cache_luminance_deltas"),180size: WORLD_CACHE_SIZE * size_of::<f32>() as u64,181usage: BufferUsages::STORAGE,182mapped_at_creation: false,183});184185let world_cache_active_cells_new_radiance =186render_device.create_buffer(&BufferDescriptor {187label: Some("solari_lighting_world_cache_active_cells_new_radiance"),188size: WORLD_CACHE_SIZE * size_of::<[f32; 4]>() as u64,189usage: BufferUsages::STORAGE,190mapped_at_creation: false,191});192193let world_cache_a = render_device.create_buffer(&BufferDescriptor {194label: Some("solari_lighting_world_cache_a"),195size: WORLD_CACHE_SIZE * size_of::<u32>() as u64,196usage: BufferUsages::STORAGE,197mapped_at_creation: false,198});199let world_cache_b = render_device.create_buffer(&BufferDescriptor {200label: Some("solari_lighting_world_cache_b"),201size: 1024 * size_of::<u32>() as u64,202usage: BufferUsages::STORAGE,203mapped_at_creation: false,204});205206let world_cache_active_cell_indices = render_device.create_buffer(&BufferDescriptor {207label: Some("solari_lighting_world_cache_active_cell_indices"),208size: WORLD_CACHE_SIZE * size_of::<u32>() as u64,209usage: BufferUsages::STORAGE,210mapped_at_creation: false,211});212213let world_cache_active_cells_count = render_device.create_buffer(&BufferDescriptor {214label: Some("solari_lighting_world_cache_active_cells_count"),215size: size_of::<u32>() as u64,216usage: BufferUsages::STORAGE | BufferUsages::COPY_SRC,217mapped_at_creation: false,218});219220let world_cache_active_cells_dispatch = render_device.create_buffer(&BufferDescriptor {221label: Some("solari_lighting_world_cache_active_cells_dispatch"),222size: size_of::<[u32; 3]>() as u64,223usage: BufferUsages::INDIRECT | BufferUsages::STORAGE,224mapped_at_creation: false,225});226227commands.entity(entity).insert(SolariLightingResources {228light_tile_samples,229light_tile_resolved_samples,230di_reservoirs_a,231di_reservoirs_b,232gi_reservoirs_a,233gi_reservoirs_b,234world_cache_checksums,235world_cache_life,236world_cache_radiance,237world_cache_geometry_data,238world_cache_luminance_deltas,239world_cache_active_cells_new_radiance,240world_cache_a,241world_cache_b,242world_cache_active_cell_indices,243world_cache_active_cells_count,244world_cache_active_cells_dispatch,245view_size,246});247248#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]249if has_dlss_rr {250let diffuse_albedo = render_device.create_texture(&TextureDescriptor {251label: Some("solari_lighting_diffuse_albedo"),252size: view_size.to_extents(),253mip_level_count: 1,254sample_count: 1,255dimension: TextureDimension::D2,256format: TextureFormat::Rgba8Unorm,257usage: TextureUsages::TEXTURE_BINDING | TextureUsages::STORAGE_BINDING,258view_formats: &[],259});260let diffuse_albedo_view = diffuse_albedo.create_view(&TextureViewDescriptor::default());261262let specular_albedo = render_device.create_texture(&TextureDescriptor {263label: Some("solari_lighting_specular_albedo"),264size: view_size.to_extents(),265mip_level_count: 1,266sample_count: 1,267dimension: TextureDimension::D2,268format: TextureFormat::Rgba8Unorm,269usage: TextureUsages::TEXTURE_BINDING | TextureUsages::STORAGE_BINDING,270view_formats: &[],271});272let specular_albedo_view =273specular_albedo.create_view(&TextureViewDescriptor::default());274275let normal_roughness = render_device.create_texture(&TextureDescriptor {276label: Some("solari_lighting_normal_roughness"),277size: view_size.to_extents(),278mip_level_count: 1,279sample_count: 1,280dimension: TextureDimension::D2,281format: TextureFormat::Rgba16Float,282usage: TextureUsages::TEXTURE_BINDING | TextureUsages::STORAGE_BINDING,283view_formats: &[],284});285let normal_roughness_view =286normal_roughness.create_view(&TextureViewDescriptor::default());287288let specular_motion_vectors = render_device.create_texture(&TextureDescriptor {289label: Some("solari_lighting_specular_motion_vectors"),290size: view_size.to_extents(),291mip_level_count: 1,292sample_count: 1,293dimension: TextureDimension::D2,294format: TextureFormat::Rg16Float,295usage: TextureUsages::TEXTURE_BINDING | TextureUsages::STORAGE_BINDING,296view_formats: &[],297});298let specular_motion_vectors_view =299specular_motion_vectors.create_view(&TextureViewDescriptor::default());300301commands302.entity(entity)303.insert(ViewDlssRayReconstructionTextures {304diffuse_albedo: CachedTexture {305texture: diffuse_albedo,306default_view: diffuse_albedo_view,307},308specular_albedo: CachedTexture {309texture: specular_albedo,310default_view: specular_albedo_view,311},312normal_roughness: CachedTexture {313texture: normal_roughness,314default_view: normal_roughness_view,315},316specular_motion_vectors: CachedTexture {317texture: specular_motion_vectors,318default_view: specular_motion_vectors_view,319},320});321}322}323}324325326