Path: blob/main/crates/bevy_solari/src/realtime/prepare.rs
6596 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;6use bevy_core_pipeline::{core_3d::CORE_3D_DEPTH_FORMAT, deferred::DEFERRED_PREPASS_FORMAT};7#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]8use bevy_ecs::query::Has;9use bevy_ecs::{10component::Component,11entity::Entity,12query::With,13system::{Commands, Query, Res},14};15use bevy_image::ToExtents;16use bevy_math::UVec2;17#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]18use bevy_render::texture::CachedTexture;19use bevy_render::{20camera::ExtractedCamera,21render_resource::{22Buffer, BufferDescriptor, BufferUsages, Texture, TextureDescriptor, TextureDimension,23TextureFormat, TextureUsages, TextureView, TextureViewDescriptor,24},25renderer::RenderDevice,26};2728/// Size of the `LightSample` shader struct in bytes.29const LIGHT_SAMPLE_STRUCT_SIZE: u64 = 8;3031/// Size of the `ResolvedLightSamplePacked` shader struct in bytes.32const RESOLVED_LIGHT_SAMPLE_STRUCT_SIZE: u64 = 24;3334/// Size of the GI `Reservoir` shader struct in bytes.35const GI_RESERVOIR_STRUCT_SIZE: u64 = 48;3637pub const LIGHT_TILE_BLOCKS: u64 = 128;38pub const LIGHT_TILE_SAMPLES_PER_BLOCK: u64 = 1024;3940/// Amount of entries in the world cache (must be a power of 2, and >= 2^10)41pub const WORLD_CACHE_SIZE: u64 = 2u64.pow(20);4243/// Internal rendering resources used for Solari lighting.44#[derive(Component)]45pub struct SolariLightingResources {46pub light_tile_samples: Buffer,47pub light_tile_resolved_samples: Buffer,48pub di_reservoirs_a: (Texture, TextureView),49pub di_reservoirs_b: (Texture, TextureView),50pub gi_reservoirs_a: Buffer,51pub gi_reservoirs_b: Buffer,52pub previous_gbuffer: (Texture, TextureView),53pub previous_depth: (Texture, TextureView),54pub world_cache_checksums: Buffer,55pub world_cache_life: Buffer,56pub world_cache_radiance: Buffer,57pub world_cache_geometry_data: Buffer,58pub world_cache_active_cells_new_radiance: Buffer,59pub world_cache_a: Buffer,60pub world_cache_b: Buffer,61pub world_cache_active_cell_indices: Buffer,62pub world_cache_active_cells_count: Buffer,63pub world_cache_active_cells_dispatch: Buffer,64pub view_size: UVec2,65}6667pub fn prepare_solari_lighting_resources(68#[cfg(any(not(feature = "dlss"), feature = "force_disable_dlss"))] query: Query<69(70Entity,71&ExtractedCamera,72Option<&SolariLightingResources>,73Option<&MainPassResolutionOverride>,74),75With<SolariLighting>,76>,77#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))] query: Query<78(79Entity,80&ExtractedCamera,81Option<&SolariLightingResources>,82Option<&MainPassResolutionOverride>,83Has<Dlss<DlssRayReconstructionFeature>>,84),85With<SolariLighting>,86>,87render_device: Res<RenderDevice>,88mut commands: Commands,89) {90for query_item in &query {91#[cfg(any(not(feature = "dlss"), feature = "force_disable_dlss"))]92let (entity, camera, solari_lighting_resources, resolution_override) = query_item;93#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]94let (entity, camera, solari_lighting_resources, resolution_override, has_dlss_rr) =95query_item;9697let Some(mut view_size) = camera.physical_viewport_size else {98continue;99};100if let Some(MainPassResolutionOverride(resolution_override)) = resolution_override {101view_size = *resolution_override;102}103104if solari_lighting_resources.map(|r| r.view_size) == Some(view_size) {105continue;106}107108let light_tile_samples = render_device.create_buffer(&BufferDescriptor {109label: Some("solari_lighting_light_tile_samples"),110size: LIGHT_TILE_BLOCKS * LIGHT_TILE_SAMPLES_PER_BLOCK * LIGHT_SAMPLE_STRUCT_SIZE,111usage: BufferUsages::STORAGE,112mapped_at_creation: false,113});114115let light_tile_resolved_samples = render_device.create_buffer(&BufferDescriptor {116label: Some("solari_lighting_light_tile_resolved_samples"),117size: LIGHT_TILE_BLOCKS118* LIGHT_TILE_SAMPLES_PER_BLOCK119* RESOLVED_LIGHT_SAMPLE_STRUCT_SIZE,120usage: BufferUsages::STORAGE,121mapped_at_creation: false,122});123124let di_reservoirs = |name| {125let tex = render_device.create_texture(&TextureDescriptor {126label: Some(name),127size: view_size.to_extents(),128mip_level_count: 1,129sample_count: 1,130dimension: TextureDimension::D2,131format: TextureFormat::Rgba32Uint,132usage: TextureUsages::STORAGE_BINDING,133view_formats: &[],134});135let view = tex.create_view(&TextureViewDescriptor::default());136(tex, view)137};138let di_reservoirs_a = di_reservoirs("solari_lighting_di_reservoirs_a");139let di_reservoirs_b = di_reservoirs("solari_lighting_di_reservoirs_b");140141let gi_reservoirs = |name| {142render_device.create_buffer(&BufferDescriptor {143label: Some(name),144size: (view_size.x * view_size.y) as u64 * GI_RESERVOIR_STRUCT_SIZE,145usage: BufferUsages::STORAGE,146mapped_at_creation: false,147})148};149let gi_reservoirs_a = gi_reservoirs("solari_lighting_gi_reservoirs_a");150let gi_reservoirs_b = gi_reservoirs("solari_lighting_gi_reservoirs_b");151152let previous_gbuffer = render_device.create_texture(&TextureDescriptor {153label: Some("solari_lighting_previous_gbuffer"),154size: view_size.to_extents(),155mip_level_count: 1,156sample_count: 1,157dimension: TextureDimension::D2,158format: DEFERRED_PREPASS_FORMAT,159usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST,160view_formats: &[],161});162let previous_gbuffer_view = previous_gbuffer.create_view(&TextureViewDescriptor::default());163164let previous_depth = render_device.create_texture(&TextureDescriptor {165label: Some("solari_lighting_previous_depth"),166size: view_size.to_extents(),167mip_level_count: 1,168sample_count: 1,169dimension: TextureDimension::D2,170format: CORE_3D_DEPTH_FORMAT,171usage: TextureUsages::TEXTURE_BINDING | TextureUsages::COPY_DST,172view_formats: &[],173});174let previous_depth_view = previous_depth.create_view(&TextureViewDescriptor::default());175176let world_cache_checksums = render_device.create_buffer(&BufferDescriptor {177label: Some("solari_lighting_world_cache_checksums"),178size: WORLD_CACHE_SIZE * size_of::<u32>() as u64,179usage: BufferUsages::STORAGE,180mapped_at_creation: false,181});182183let world_cache_life = render_device.create_buffer(&BufferDescriptor {184label: Some("solari_lighting_world_cache_life"),185size: WORLD_CACHE_SIZE * size_of::<u32>() as u64,186usage: BufferUsages::STORAGE,187mapped_at_creation: false,188});189190let world_cache_radiance = render_device.create_buffer(&BufferDescriptor {191label: Some("solari_lighting_world_cache_radiance"),192size: WORLD_CACHE_SIZE * size_of::<[f32; 4]>() as u64,193usage: BufferUsages::STORAGE,194mapped_at_creation: false,195});196197let world_cache_geometry_data = render_device.create_buffer(&BufferDescriptor {198label: Some("solari_lighting_world_cache_geometry_data"),199size: WORLD_CACHE_SIZE * size_of::<[f32; 8]>() as u64,200usage: BufferUsages::STORAGE,201mapped_at_creation: false,202});203204let world_cache_active_cells_new_radiance =205render_device.create_buffer(&BufferDescriptor {206label: Some("solari_lighting_world_cache_active_cells_new_irradiance"),207size: WORLD_CACHE_SIZE * size_of::<[f32; 4]>() as u64,208usage: BufferUsages::STORAGE,209mapped_at_creation: false,210});211212let world_cache_a = render_device.create_buffer(&BufferDescriptor {213label: Some("solari_lighting_world_cache_a"),214size: WORLD_CACHE_SIZE * size_of::<u32>() as u64,215usage: BufferUsages::STORAGE,216mapped_at_creation: false,217});218let world_cache_b = render_device.create_buffer(&BufferDescriptor {219label: Some("solari_lighting_world_cache_b"),220size: 1024 * size_of::<u32>() as u64,221usage: BufferUsages::STORAGE,222mapped_at_creation: false,223});224225let world_cache_active_cell_indices = render_device.create_buffer(&BufferDescriptor {226label: Some("solari_lighting_world_cache_active_cell_indices"),227size: WORLD_CACHE_SIZE * size_of::<u32>() as u64,228usage: BufferUsages::STORAGE,229mapped_at_creation: false,230});231232let world_cache_active_cells_count = render_device.create_buffer(&BufferDescriptor {233label: Some("solari_lighting_world_cache_active_cells_count"),234size: size_of::<u32>() as u64,235usage: BufferUsages::STORAGE,236mapped_at_creation: false,237});238239let world_cache_active_cells_dispatch = render_device.create_buffer(&BufferDescriptor {240label: Some("solari_lighting_world_cache_active_cells_dispatch"),241size: size_of::<[u32; 3]>() as u64,242usage: BufferUsages::INDIRECT | BufferUsages::STORAGE,243mapped_at_creation: false,244});245246commands.entity(entity).insert(SolariLightingResources {247light_tile_samples,248light_tile_resolved_samples,249di_reservoirs_a,250di_reservoirs_b,251gi_reservoirs_a,252gi_reservoirs_b,253previous_gbuffer: (previous_gbuffer, previous_gbuffer_view),254previous_depth: (previous_depth, previous_depth_view),255world_cache_checksums,256world_cache_life,257world_cache_radiance,258world_cache_geometry_data,259world_cache_active_cells_new_radiance,260world_cache_a,261world_cache_b,262world_cache_active_cell_indices,263world_cache_active_cells_count,264world_cache_active_cells_dispatch,265view_size,266});267268#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]269if has_dlss_rr {270let diffuse_albedo = render_device.create_texture(&TextureDescriptor {271label: Some("solari_lighting_diffuse_albedo"),272size: view_size.to_extents(),273mip_level_count: 1,274sample_count: 1,275dimension: TextureDimension::D2,276format: TextureFormat::Rgba8Unorm,277usage: TextureUsages::TEXTURE_BINDING | TextureUsages::STORAGE_BINDING,278view_formats: &[],279});280let diffuse_albedo_view = diffuse_albedo.create_view(&TextureViewDescriptor::default());281282let specular_albedo = render_device.create_texture(&TextureDescriptor {283label: Some("solari_lighting_specular_albedo"),284size: view_size.to_extents(),285mip_level_count: 1,286sample_count: 1,287dimension: TextureDimension::D2,288format: TextureFormat::Rgba8Unorm,289usage: TextureUsages::TEXTURE_BINDING | TextureUsages::STORAGE_BINDING,290view_formats: &[],291});292let specular_albedo_view =293specular_albedo.create_view(&TextureViewDescriptor::default());294295let normal_roughness = render_device.create_texture(&TextureDescriptor {296label: Some("solari_lighting_normal_roughness"),297size: view_size.to_extents(),298mip_level_count: 1,299sample_count: 1,300dimension: TextureDimension::D2,301format: TextureFormat::Rgba16Float,302usage: TextureUsages::TEXTURE_BINDING | TextureUsages::STORAGE_BINDING,303view_formats: &[],304});305let normal_roughness_view =306normal_roughness.create_view(&TextureViewDescriptor::default());307308let specular_motion_vectors = render_device.create_texture(&TextureDescriptor {309label: Some("solari_lighting_specular_motion_vectors"),310size: view_size.to_extents(),311mip_level_count: 1,312sample_count: 1,313dimension: TextureDimension::D2,314format: TextureFormat::Rg16Float,315usage: TextureUsages::TEXTURE_BINDING | TextureUsages::STORAGE_BINDING,316view_formats: &[],317});318let specular_motion_vectors_view =319specular_motion_vectors.create_view(&TextureViewDescriptor::default());320321commands322.entity(entity)323.insert(ViewDlssRayReconstructionTextures {324diffuse_albedo: CachedTexture {325texture: diffuse_albedo,326default_view: diffuse_albedo_view,327},328specular_albedo: CachedTexture {329texture: specular_albedo,330default_view: specular_albedo_view,331},332normal_roughness: CachedTexture {333texture: normal_roughness,334default_view: normal_roughness_view,335},336specular_motion_vectors: CachedTexture {337texture: specular_motion_vectors,338default_view: specular_motion_vectors_view,339},340});341}342}343}344345346