Skip to content

Commit 2eec49d

Browse files
authored
Tweak solari world cache (#21776)
* Make the world cache transition LODs faster. On big scenes like bistro, we had way too many small cells before. * Limit world cache GI rays to 4m, we save a ton of time and improve stability by not sampling super far away cells. * Switch world cache active cell update workgroup size from 1024 -> 64. Using large workgroup sizes for RT work kills occupancy. World cache sample_radiance time goes from 1.42ms to 0.09ms.
1 parent e1de883 commit 2eec49d

File tree

3 files changed

+7
-6
lines changed

3 files changed

+7
-6
lines changed

crates/bevy_solari/src/realtime/world_cache_compact.wgsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,6 @@ fn compact_world_cache_write_active_cells(
6565

6666
if thread_index == 1023u && workgroup_id.x == 1023u {
6767
world_cache_active_cells_count = compacted_index + 1u; // TODO: This is 1 even when there are zero active entries in the cache
68-
world_cache_active_cells_dispatch = vec3((world_cache_active_cells_count + 1023u) / 1024u, 1u, 1u);
68+
world_cache_active_cells_dispatch = vec3((world_cache_active_cells_count + 63u) / 64u, 1u, 1u);
6969
}
7070
}

crates/bevy_solari/src/realtime/world_cache_query.wgsl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ const WORLD_CACHE_MAX_SEARCH_STEPS: u32 = 3u;
1313
/// The size of a cache cell at the lowest LOD in meters
1414
const WORLD_CACHE_POSITION_BASE_CELL_SIZE: f32 = 0.25;
1515
/// How fast the world cache transitions between LODs as a function of distance to the camera
16-
const WORLD_CACHE_POSITION_LOD_SCALE: f32 = 30.0;
16+
const WORLD_CACHE_POSITION_LOD_SCALE: f32 = 8.0;
1717

1818
/// Marker value for an empty cell
1919
const WORLD_CACHE_EMPTY_CELL: u32 = 0u;

crates/bevy_solari/src/realtime/world_cache_update.wgsl

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
#import bevy_render::view::View
44
#import bevy_solari::presample_light_tiles::{ResolvedLightSamplePacked, unpack_resolved_light_sample}
55
#import bevy_solari::sampling::{calculate_resolved_light_contribution, trace_light_visibility}
6-
#import bevy_solari::scene_bindings::{trace_ray, resolve_ray_hit_full, RAY_T_MIN, RAY_T_MAX}
6+
#import bevy_solari::scene_bindings::{trace_ray, resolve_ray_hit_full, RAY_T_MIN}
77
#import bevy_solari::world_cache::{
88
WORLD_CACHE_MAX_TEMPORAL_SAMPLES,
99
query_world_cache,
@@ -20,8 +20,9 @@ struct PushConstants { frame_index: u32, reset: u32 }
2020
var<push_constant> constants: PushConstants;
2121

2222
const DIRECT_LIGHT_SAMPLE_COUNT: u32 = 32u;
23+
const MAX_GI_RAY_DISTANCE: f32 = 4.0;
2324

24-
@compute @workgroup_size(1024, 1, 1)
25+
@compute @workgroup_size(64, 1, 1)
2526
fn sample_radiance(@builtin(workgroup_id) workgroup_id: vec3<u32>, @builtin(global_invocation_id) active_cell_id: vec3<u32>) {
2627
if active_cell_id.x < world_cache_active_cells_count {
2728
let cell_index = world_cache_active_cell_indices[active_cell_id.x];
@@ -34,7 +35,7 @@ fn sample_radiance(@builtin(workgroup_id) workgroup_id: vec3<u32>, @builtin(glob
3435

3536
#ifndef NO_MULTIBOUNCE
3637
let ray_direction = sample_cosine_hemisphere(geometry_data.world_normal, &rng);
37-
let ray_hit = trace_ray(geometry_data.world_position, ray_direction, RAY_T_MIN, RAY_T_MAX, RAY_FLAG_NONE);
38+
let ray_hit = trace_ray(geometry_data.world_position, ray_direction, RAY_T_MIN, MAX_GI_RAY_DISTANCE, RAY_FLAG_NONE);
3839
if ray_hit.kind != RAY_QUERY_INTERSECTION_NONE {
3940
let ray_hit = resolve_ray_hit_full(ray_hit);
4041
new_radiance += ray_hit.material.base_color * query_world_cache(ray_hit.world_position, ray_hit.geometric_world_normal, view.world_position, &rng);
@@ -45,7 +46,7 @@ fn sample_radiance(@builtin(workgroup_id) workgroup_id: vec3<u32>, @builtin(glob
4546
}
4647
}
4748

48-
@compute @workgroup_size(1024, 1, 1)
49+
@compute @workgroup_size(64, 1, 1)
4950
fn blend_new_samples(@builtin(global_invocation_id) active_cell_id: vec3<u32>) {
5051
if active_cell_id.x < world_cache_active_cells_count {
5152
let cell_index = world_cache_active_cell_indices[active_cell_id.x];

0 commit comments

Comments
 (0)