Skip to content

Commit b6945e5

Browse files
authored
Stop copying the light probe array to the stack in the shader. (#11805)
This was causing a severe performance regression when light probes were enabled. Fixes #11787.
1 parent 2e2f898 commit b6945e5

3 files changed

Lines changed: 17 additions & 14 deletions

File tree

crates/bevy_pbr/src/light_probe/environment_map.wgsl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,7 @@ fn compute_radiances(
3030
var radiances: EnvironmentMapRadiances;
3131

3232
// Search for a reflection probe that contains the fragment.
33-
var query_result = query_light_probe(
34-
light_probes.reflection_probes,
35-
light_probes.reflection_probe_count,
36-
world_position);
33+
var query_result = query_light_probe(world_position, /*is_irradiance_volume=*/ false);
3734

3835
// If we didn't find a reflection probe, use the view environment map if applicable.
3936
if (query_result.texture_index < 0) {

crates/bevy_pbr/src/light_probe/irradiance_volume.wgsl

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,7 @@
1313
// Slide 28, "Ambient Cube Basis"
1414
fn irradiance_volume_light(world_position: vec3<f32>, N: vec3<f32>) -> vec3<f32> {
1515
// Search for an irradiance volume that contains the fragment.
16-
let query_result = query_light_probe(
17-
light_probes.irradiance_volumes,
18-
light_probes.irradiance_volume_count,
19-
world_position);
16+
let query_result = query_light_probe(world_position, /*is_irradiance_volume=*/ true);
2017

2118
// If there was no irradiance volume found, bail out.
2219
if (query_result.texture_index < 0) {

crates/bevy_pbr/src/light_probe/light_probe.wgsl

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#define_import_path bevy_pbr::light_probe
22

3+
#import bevy_pbr::mesh_view_bindings::light_probes
34
#import bevy_pbr::mesh_view_types::LightProbe
45

56
// The result of searching for a light probe.
@@ -28,20 +29,28 @@ fn transpose_affine_matrix(matrix: mat3x4<f32>) -> mat4x4<f32> {
2829
//
2930
// TODO: Interpolate between multiple light probes.
3031
fn query_light_probe(
31-
in_light_probes: array<LightProbe, 8u>,
32-
light_probe_count: i32,
3332
world_position: vec3<f32>,
33+
is_irradiance_volume: bool,
3434
) -> LightProbeQueryResult {
35-
// This is needed to index into the array with a non-constant expression.
36-
var light_probes = in_light_probes;
37-
3835
var result: LightProbeQueryResult;
3936
result.texture_index = -1;
4037

38+
var light_probe_count: i32;
39+
if is_irradiance_volume {
40+
light_probe_count = light_probes.irradiance_volume_count;
41+
} else {
42+
light_probe_count = light_probes.reflection_probe_count;
43+
}
44+
4145
for (var light_probe_index: i32 = 0;
4246
light_probe_index < light_probe_count && result.texture_index < 0;
4347
light_probe_index += 1) {
44-
let light_probe = light_probes[light_probe_index];
48+
var light_probe: LightProbe;
49+
if is_irradiance_volume {
50+
light_probe = light_probes.irradiance_volumes[light_probe_index];
51+
} else {
52+
light_probe = light_probes.reflection_probes[light_probe_index];
53+
}
4554

4655
// Unpack the inverse transform.
4756
let inverse_transform =

0 commit comments

Comments
 (0)