1#define_import_path bevy_pbr::light_probe3#import bevy_pbr::mesh_view_bindings::light_probes4#import bevy_pbr::mesh_view_types::LightProbe6// The result of searching for a light probe.7struct LightProbeQueryResult {8 // The index of the light probe texture or textures in the binding array or9 // arrays.10 texture_index: i32,11 // A scale factor that's applied to the diffuse and specular light from the12 // light probe. This is in units of cd/m² (candela per square meter).13 intensity: f32,14 // Transform from world space to the light probe model space. In light probe15 // model space, the light probe is a 1×1×1 cube centered on the origin.16 light_from_world: mat4x4<f32>,17};19fn transpose_affine_matrix(matrix: mat3x4<f32>) -> mat4x4<f32> {20 let matrix4x4 = mat4x4<f32>(21 matrix[0],22 matrix[1],23 matrix[2],24 vec4<f32>(0.0, 0.0, 0.0, 1.0));25 return transpose(matrix4x4);26}28// Searches for a light probe that contains the fragment.29//30// TODO: Interpolate between multiple light probes.31fn query_light_probe(32 world_position: vec3<f32>,33 is_irradiance_volume: bool,34) -> LightProbeQueryResult {35 var result: LightProbeQueryResult;36 result.texture_index = -1;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 }45 for (var light_probe_index: i32 = 0;46 light_probe_index < light_probe_count && result.texture_index < 0;47 light_probe_index += 1) {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 }55 // Unpack the inverse transform.56 let light_from_world =57 transpose_affine_matrix(light_probe.light_from_world_transposed);59 // Check to see if the transformed point is inside the unit cube60 // centered at the origin.61 let probe_space_pos = (light_from_world * vec4<f32>(world_position, 1.0f)).xyz;62 if (all(abs(probe_space_pos) <= vec3(0.5f))) {63 result.texture_index = light_probe.cubemap_index;64 result.intensity = light_probe.intensity;65 result.light_from_world = light_from_world;67 // TODO: Workaround for ICE in DXC https://github.com/microsoft/DirectXShaderCompiler/issues/618368 // We can't use `break` here because of the ICE.69 // So instead we rely on the fact that we set `result.texture_index`70 // above and check its value in the `for` loop header before71 // looping.72 // break;73 }74 }76 return result;77}