Path: blob/main/crates/bevy_solari/src/realtime/node.rs
6596 views
use super::{1prepare::{SolariLightingResources, LIGHT_TILE_BLOCKS, WORLD_CACHE_SIZE},2SolariLighting,3};4use crate::scene::RaytracingSceneBindings;5#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]6use bevy_anti_alias::dlss::ViewDlssRayReconstructionTextures;7use bevy_asset::{load_embedded_asset, Handle};8use bevy_core_pipeline::prepass::{9PreviousViewData, PreviousViewUniformOffset, PreviousViewUniforms, ViewPrepassTextures,10};11use bevy_diagnostic::FrameCount;12use bevy_ecs::{13query::QueryItem,14world::{FromWorld, World},15};16use bevy_image::ToExtents;17use bevy_render::{18diagnostic::RecordDiagnostics,19render_graph::{NodeRunError, RenderGraphContext, ViewNode},20render_resource::{21binding_types::{22storage_buffer_sized, texture_2d, texture_depth_2d, texture_storage_2d, uniform_buffer,23},24BindGroupEntries, BindGroupLayout, BindGroupLayoutEntries, CachedComputePipelineId,25ComputePassDescriptor, ComputePipelineDescriptor, PipelineCache, PushConstantRange,26ShaderStages, StorageTextureAccess, TextureFormat, TextureSampleType,27},28renderer::{RenderContext, RenderDevice},29view::{ViewTarget, ViewUniform, ViewUniformOffset, ViewUniforms},30};31use bevy_shader::{Shader, ShaderDefVal};32use bevy_utils::default;3334pub mod graph {35use bevy_render::render_graph::RenderLabel;3637#[derive(Debug, Hash, PartialEq, Eq, Clone, RenderLabel)]38pub struct SolariLightingNode;39}4041pub struct SolariLightingNode {42bind_group_layout: BindGroupLayout,43bind_group_layout_world_cache_active_cells_dispatch: BindGroupLayout,44#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]45bind_group_layout_resolve_dlss_rr_textures: BindGroupLayout,46decay_world_cache_pipeline: CachedComputePipelineId,47compact_world_cache_single_block_pipeline: CachedComputePipelineId,48compact_world_cache_blocks_pipeline: CachedComputePipelineId,49compact_world_cache_write_active_cells_pipeline: CachedComputePipelineId,50sample_for_world_cache_pipeline: CachedComputePipelineId,51blend_new_world_cache_samples_pipeline: CachedComputePipelineId,52presample_light_tiles_pipeline: CachedComputePipelineId,53di_initial_and_temporal_pipeline: CachedComputePipelineId,54di_spatial_and_shade_pipeline: CachedComputePipelineId,55gi_initial_and_temporal_pipeline: CachedComputePipelineId,56gi_spatial_and_shade_pipeline: CachedComputePipelineId,57#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]58resolve_dlss_rr_textures_pipeline: CachedComputePipelineId,59}6061impl ViewNode for SolariLightingNode {62#[cfg(any(not(feature = "dlss"), feature = "force_disable_dlss"))]63type ViewQuery = (64&'static SolariLighting,65&'static SolariLightingResources,66&'static ViewTarget,67&'static ViewPrepassTextures,68&'static ViewUniformOffset,69&'static PreviousViewUniformOffset,70);71#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]72type ViewQuery = (73&'static SolariLighting,74&'static SolariLightingResources,75&'static ViewTarget,76&'static ViewPrepassTextures,77&'static ViewUniformOffset,78&'static PreviousViewUniformOffset,79Option<&'static ViewDlssRayReconstructionTextures>,80);8182fn run(83&self,84_graph: &mut RenderGraphContext,85render_context: &mut RenderContext,86#[cfg(any(not(feature = "dlss"), feature = "force_disable_dlss"))] (87solari_lighting,88solari_lighting_resources,89view_target,90view_prepass_textures,91view_uniform_offset,92previous_view_uniform_offset,93): QueryItem<Self::ViewQuery>,94#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))] (95solari_lighting,96solari_lighting_resources,97view_target,98view_prepass_textures,99view_uniform_offset,100previous_view_uniform_offset,101view_dlss_rr_textures,102): QueryItem<Self::ViewQuery>,103world: &World,104) -> Result<(), NodeRunError> {105let pipeline_cache = world.resource::<PipelineCache>();106let scene_bindings = world.resource::<RaytracingSceneBindings>();107let view_uniforms = world.resource::<ViewUniforms>();108let previous_view_uniforms = world.resource::<PreviousViewUniforms>();109let frame_count = world.resource::<FrameCount>();110let (111Some(decay_world_cache_pipeline),112Some(compact_world_cache_single_block_pipeline),113Some(compact_world_cache_blocks_pipeline),114Some(compact_world_cache_write_active_cells_pipeline),115Some(sample_for_world_cache_pipeline),116Some(blend_new_world_cache_samples_pipeline),117Some(presample_light_tiles_pipeline),118Some(di_initial_and_temporal_pipeline),119Some(di_spatial_and_shade_pipeline),120Some(gi_initial_and_temporal_pipeline),121Some(gi_spatial_and_shade_pipeline),122Some(scene_bindings),123Some(gbuffer),124Some(depth_buffer),125Some(motion_vectors),126Some(view_uniforms),127Some(previous_view_uniforms),128) = (129pipeline_cache.get_compute_pipeline(self.decay_world_cache_pipeline),130pipeline_cache.get_compute_pipeline(self.compact_world_cache_single_block_pipeline),131pipeline_cache.get_compute_pipeline(self.compact_world_cache_blocks_pipeline),132pipeline_cache133.get_compute_pipeline(self.compact_world_cache_write_active_cells_pipeline),134pipeline_cache.get_compute_pipeline(self.sample_for_world_cache_pipeline),135pipeline_cache.get_compute_pipeline(self.blend_new_world_cache_samples_pipeline),136pipeline_cache.get_compute_pipeline(self.presample_light_tiles_pipeline),137pipeline_cache.get_compute_pipeline(self.di_initial_and_temporal_pipeline),138pipeline_cache.get_compute_pipeline(self.di_spatial_and_shade_pipeline),139pipeline_cache.get_compute_pipeline(self.gi_initial_and_temporal_pipeline),140pipeline_cache.get_compute_pipeline(self.gi_spatial_and_shade_pipeline),141&scene_bindings.bind_group,142view_prepass_textures.deferred_view(),143view_prepass_textures.depth_view(),144view_prepass_textures.motion_vectors_view(),145view_uniforms.uniforms.binding(),146previous_view_uniforms.uniforms.binding(),147)148else {149return Ok(());150};151#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]152let Some(resolve_dlss_rr_textures_pipeline) =153pipeline_cache.get_compute_pipeline(self.resolve_dlss_rr_textures_pipeline)154else {155return Ok(());156};157158let s = solari_lighting_resources;159let bind_group = render_context.render_device().create_bind_group(160"solari_lighting_bind_group",161&self.bind_group_layout,162&BindGroupEntries::sequential((163view_target.get_unsampled_color_attachment().view,164s.light_tile_samples.as_entire_binding(),165s.light_tile_resolved_samples.as_entire_binding(),166&s.di_reservoirs_a.1,167&s.di_reservoirs_b.1,168s.gi_reservoirs_a.as_entire_binding(),169s.gi_reservoirs_b.as_entire_binding(),170gbuffer,171depth_buffer,172motion_vectors,173&s.previous_gbuffer.1,174&s.previous_depth.1,175view_uniforms,176previous_view_uniforms,177s.world_cache_checksums.as_entire_binding(),178s.world_cache_life.as_entire_binding(),179s.world_cache_radiance.as_entire_binding(),180s.world_cache_geometry_data.as_entire_binding(),181s.world_cache_active_cells_new_radiance.as_entire_binding(),182s.world_cache_a.as_entire_binding(),183s.world_cache_b.as_entire_binding(),184s.world_cache_active_cell_indices.as_entire_binding(),185s.world_cache_active_cells_count.as_entire_binding(),186)),187);188let bind_group_world_cache_active_cells_dispatch =189render_context.render_device().create_bind_group(190"solari_lighting_bind_group_world_cache_active_cells_dispatch",191&self.bind_group_layout_world_cache_active_cells_dispatch,192&BindGroupEntries::single(s.world_cache_active_cells_dispatch.as_entire_binding()),193);194#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]195let bind_group_resolve_dlss_rr_textures = view_dlss_rr_textures.map(|d| {196render_context.render_device().create_bind_group(197"solari_lighting_bind_group_resolve_dlss_rr_textures",198&self.bind_group_layout_resolve_dlss_rr_textures,199&BindGroupEntries::sequential((200&d.diffuse_albedo.default_view,201&d.specular_albedo.default_view,202&d.normal_roughness.default_view,203&d.specular_motion_vectors.default_view,204)),205)206});207208// Choice of number here is arbitrary209let frame_index = frame_count.0.wrapping_mul(5782582);210211let diagnostics = render_context.diagnostic_recorder();212let command_encoder = render_context.command_encoder();213214let mut pass = command_encoder.begin_compute_pass(&ComputePassDescriptor {215label: Some("solari_lighting"),216timestamp_writes: None,217});218let pass_span = diagnostics.pass_span(&mut pass, "solari_lighting");219220let dx = solari_lighting_resources.view_size.x.div_ceil(8);221let dy = solari_lighting_resources.view_size.y.div_ceil(8);222223pass.set_bind_group(0, scene_bindings, &[]);224pass.set_bind_group(2251,226&bind_group,227&[228view_uniform_offset.offset,229previous_view_uniform_offset.offset,230],231);232233#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]234if let Some(bind_group_resolve_dlss_rr_textures) = bind_group_resolve_dlss_rr_textures {235pass.set_bind_group(2, &bind_group_resolve_dlss_rr_textures, &[]);236pass.set_pipeline(resolve_dlss_rr_textures_pipeline);237pass.dispatch_workgroups(dx, dy, 1);238}239240pass.set_bind_group(2, &bind_group_world_cache_active_cells_dispatch, &[]);241242pass.set_pipeline(decay_world_cache_pipeline);243pass.dispatch_workgroups((WORLD_CACHE_SIZE / 1024) as u32, 1, 1);244245pass.set_pipeline(compact_world_cache_single_block_pipeline);246pass.dispatch_workgroups((WORLD_CACHE_SIZE / 1024) as u32, 1, 1);247248pass.set_pipeline(compact_world_cache_blocks_pipeline);249pass.dispatch_workgroups(1, 1, 1);250251pass.set_pipeline(compact_world_cache_write_active_cells_pipeline);252pass.dispatch_workgroups((WORLD_CACHE_SIZE / 1024) as u32, 1, 1);253254pass.set_bind_group(2, None, &[]);255256pass.set_pipeline(sample_for_world_cache_pipeline);257pass.set_push_constants(2580,259bytemuck::cast_slice(&[frame_index, solari_lighting.reset as u32]),260);261pass.dispatch_workgroups_indirect(262&solari_lighting_resources.world_cache_active_cells_dispatch,2630,264);265266pass.set_pipeline(blend_new_world_cache_samples_pipeline);267pass.dispatch_workgroups_indirect(268&solari_lighting_resources.world_cache_active_cells_dispatch,2690,270);271272pass.set_pipeline(presample_light_tiles_pipeline);273pass.set_push_constants(2740,275bytemuck::cast_slice(&[frame_index, solari_lighting.reset as u32]),276);277pass.dispatch_workgroups(LIGHT_TILE_BLOCKS as u32, 1, 1);278279pass.set_pipeline(di_initial_and_temporal_pipeline);280pass.set_push_constants(2810,282bytemuck::cast_slice(&[frame_index, solari_lighting.reset as u32]),283);284pass.dispatch_workgroups(dx, dy, 1);285286pass.set_pipeline(di_spatial_and_shade_pipeline);287pass.set_push_constants(2880,289bytemuck::cast_slice(&[frame_index, solari_lighting.reset as u32]),290);291pass.dispatch_workgroups(dx, dy, 1);292293pass.set_pipeline(gi_initial_and_temporal_pipeline);294pass.set_push_constants(2950,296bytemuck::cast_slice(&[frame_index, solari_lighting.reset as u32]),297);298pass.dispatch_workgroups(dx, dy, 1);299300pass.set_pipeline(gi_spatial_and_shade_pipeline);301pass.set_push_constants(3020,303bytemuck::cast_slice(&[frame_index, solari_lighting.reset as u32]),304);305pass.dispatch_workgroups(dx, dy, 1);306307pass_span.end(&mut pass);308drop(pass);309310// TODO: Remove these copies, and double buffer instead311command_encoder.copy_texture_to_texture(312view_prepass_textures313.deferred314.clone()315.unwrap()316.texture317.texture318.as_image_copy(),319solari_lighting_resources.previous_gbuffer.0.as_image_copy(),320solari_lighting_resources.view_size.to_extents(),321);322command_encoder.copy_texture_to_texture(323view_prepass_textures324.depth325.clone()326.unwrap()327.texture328.texture329.as_image_copy(),330solari_lighting_resources.previous_depth.0.as_image_copy(),331solari_lighting_resources.view_size.to_extents(),332);333334Ok(())335}336}337338impl FromWorld for SolariLightingNode {339fn from_world(world: &mut World) -> Self {340let render_device = world.resource::<RenderDevice>();341let pipeline_cache = world.resource::<PipelineCache>();342let scene_bindings = world.resource::<RaytracingSceneBindings>();343344let bind_group_layout = render_device.create_bind_group_layout(345"solari_lighting_bind_group_layout",346&BindGroupLayoutEntries::sequential(347ShaderStages::COMPUTE,348(349texture_storage_2d(350ViewTarget::TEXTURE_FORMAT_HDR,351StorageTextureAccess::ReadWrite,352),353storage_buffer_sized(false, None),354storage_buffer_sized(false, None),355texture_storage_2d(TextureFormat::Rgba32Uint, StorageTextureAccess::ReadWrite),356texture_storage_2d(TextureFormat::Rgba32Uint, StorageTextureAccess::ReadWrite),357storage_buffer_sized(false, None),358storage_buffer_sized(false, None),359texture_2d(TextureSampleType::Uint),360texture_depth_2d(),361texture_2d(TextureSampleType::Float { filterable: true }),362texture_2d(TextureSampleType::Uint),363texture_depth_2d(),364uniform_buffer::<ViewUniform>(true),365uniform_buffer::<PreviousViewData>(true),366storage_buffer_sized(false, None),367storage_buffer_sized(false, None),368storage_buffer_sized(false, None),369storage_buffer_sized(false, None),370storage_buffer_sized(false, None),371storage_buffer_sized(false, None),372storage_buffer_sized(false, None),373storage_buffer_sized(false, None),374storage_buffer_sized(false, None),375),376),377);378379let bind_group_layout_world_cache_active_cells_dispatch = render_device380.create_bind_group_layout(381"solari_lighting_bind_group_layout_world_cache_active_cells_dispatch",382&BindGroupLayoutEntries::single(383ShaderStages::COMPUTE,384storage_buffer_sized(false, None),385),386);387388#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]389let bind_group_layout_resolve_dlss_rr_textures = render_device.create_bind_group_layout(390"solari_lighting_bind_group_layout_resolve_dlss_rr_textures",391&BindGroupLayoutEntries::sequential(392ShaderStages::COMPUTE,393(394texture_storage_2d(TextureFormat::Rgba8Unorm, StorageTextureAccess::WriteOnly),395texture_storage_2d(TextureFormat::Rgba8Unorm, StorageTextureAccess::WriteOnly),396texture_storage_2d(TextureFormat::Rgba16Float, StorageTextureAccess::WriteOnly),397texture_storage_2d(TextureFormat::Rg16Float, StorageTextureAccess::WriteOnly),398),399),400);401402let create_pipeline = |label: &'static str,403entry_point: &'static str,404shader: Handle<Shader>,405extra_bind_group_layout: Option<&BindGroupLayout>,406extra_shader_defs: Vec<ShaderDefVal>| {407let mut layout = vec![408scene_bindings.bind_group_layout.clone(),409bind_group_layout.clone(),410];411if let Some(extra_bind_group_layout) = extra_bind_group_layout {412layout.push(extra_bind_group_layout.clone());413}414415let mut shader_defs = vec![ShaderDefVal::UInt(416"WORLD_CACHE_SIZE".into(),417WORLD_CACHE_SIZE as u32,418)];419shader_defs.extend_from_slice(&extra_shader_defs);420421pipeline_cache.queue_compute_pipeline(ComputePipelineDescriptor {422label: Some(label.into()),423layout,424push_constant_ranges: vec![PushConstantRange {425stages: ShaderStages::COMPUTE,426range: 0..8,427}],428shader,429shader_defs,430entry_point: Some(entry_point.into()),431..default()432})433};434435Self {436bind_group_layout: bind_group_layout.clone(),437bind_group_layout_world_cache_active_cells_dispatch:438bind_group_layout_world_cache_active_cells_dispatch.clone(),439#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]440bind_group_layout_resolve_dlss_rr_textures: bind_group_layout_resolve_dlss_rr_textures441.clone(),442decay_world_cache_pipeline: create_pipeline(443"solari_lighting_decay_world_cache_pipeline",444"decay_world_cache",445load_embedded_asset!(world, "world_cache_compact.wgsl"),446Some(&bind_group_layout_world_cache_active_cells_dispatch),447vec!["WORLD_CACHE_NON_ATOMIC_LIFE_BUFFER".into()],448),449compact_world_cache_single_block_pipeline: create_pipeline(450"solari_lighting_compact_world_cache_single_block_pipeline",451"compact_world_cache_single_block",452load_embedded_asset!(world, "world_cache_compact.wgsl"),453Some(&bind_group_layout_world_cache_active_cells_dispatch),454vec!["WORLD_CACHE_NON_ATOMIC_LIFE_BUFFER".into()],455),456compact_world_cache_blocks_pipeline: create_pipeline(457"solari_lighting_compact_world_cache_blocks_pipeline",458"compact_world_cache_blocks",459load_embedded_asset!(world, "world_cache_compact.wgsl"),460Some(&bind_group_layout_world_cache_active_cells_dispatch),461vec![],462),463compact_world_cache_write_active_cells_pipeline: create_pipeline(464"solari_lighting_compact_world_cache_write_active_cells_pipeline",465"compact_world_cache_write_active_cells",466load_embedded_asset!(world, "world_cache_compact.wgsl"),467Some(&bind_group_layout_world_cache_active_cells_dispatch),468vec!["WORLD_CACHE_NON_ATOMIC_LIFE_BUFFER".into()],469),470sample_for_world_cache_pipeline: create_pipeline(471"solari_lighting_sample_for_world_cache_pipeline",472"sample_radiance",473load_embedded_asset!(world, "world_cache_update.wgsl"),474None,475vec![],476),477blend_new_world_cache_samples_pipeline: create_pipeline(478"solari_lighting_blend_new_world_cache_samples_pipeline",479"blend_new_samples",480load_embedded_asset!(world, "world_cache_update.wgsl"),481None,482vec![],483),484presample_light_tiles_pipeline: create_pipeline(485"solari_lighting_presample_light_tiles_pipeline",486"presample_light_tiles",487load_embedded_asset!(world, "presample_light_tiles.wgsl"),488None,489vec![],490),491di_initial_and_temporal_pipeline: create_pipeline(492"solari_lighting_di_initial_and_temporal_pipeline",493"initial_and_temporal",494load_embedded_asset!(world, "restir_di.wgsl"),495None,496vec![],497),498di_spatial_and_shade_pipeline: create_pipeline(499"solari_lighting_di_spatial_and_shade_pipeline",500"spatial_and_shade",501load_embedded_asset!(world, "restir_di.wgsl"),502None,503vec![],504),505gi_initial_and_temporal_pipeline: create_pipeline(506"solari_lighting_gi_initial_and_temporal_pipeline",507"initial_and_temporal",508load_embedded_asset!(world, "restir_gi.wgsl"),509None,510vec![],511),512gi_spatial_and_shade_pipeline: create_pipeline(513"solari_lighting_gi_spatial_and_shade_pipeline",514"spatial_and_shade",515load_embedded_asset!(world, "restir_gi.wgsl"),516None,517vec![],518),519#[cfg(all(feature = "dlss", not(feature = "force_disable_dlss")))]520resolve_dlss_rr_textures_pipeline: create_pipeline(521"solari_lighting_resolve_dlss_rr_textures_pipeline",522"resolve_dlss_rr_textures",523load_embedded_asset!(world, "resolve_dlss_rr_textures.wgsl"),524Some(&bind_group_layout_resolve_dlss_rr_textures),525vec![],526),527}528}529}530531532