Constant PROBE_WGSL
Source pub const PROBE_WGSL: &str = r#"
override use_probes: bool = true;
struct ProbeLocal {
min_spacing: vec4f,
dims: vec4u,
}
struct ProbeGridInfo {
min_spacing: vec4f,
dims: vec4u,
fallback: vec4f,
blend: vec4f,
shade: vec4f,
locals: array<ProbeLocal, 4>,
}
@group(3) @binding(6) var<storage, read> probe_lower: array<u32>;
@group(3) @binding(7) var<storage, read> probe_upper: array<u32>;
@group(3) @binding(8) var<uniform> probe_grid: ProbeGridInfo;
fn probe_word(anchor: u32, index: u32) -> u32 {
if (anchor == 0u) { return probe_lower[index]; }
return probe_upper[index];
}
fn probe_block(anchor: u32, offset: u32) -> array<u32, 18> {
var block: array<u32, 18>;
if (anchor == 0u) {
for (var k = 0u; k < 18u; k++) { block[k] = probe_lower[offset + k]; }
} else {
for (var k = 0u; k < 18u; k++) { block[k] = probe_upper[offset + k]; }
}
return block;
}
fn probe_index(xyz: vec3u, dims: vec4u) -> u32 {
return (xyz.z * dims.y + xyz.y) * dims.x + xyz.x;
}
fn sample_probe_volume(position: vec3f, n: vec3f, point: vec3f, anchor: u32, origin: vec4f, dims: vec4u, words: u32, toward: vec3f, seen: ptr<function, f32>) -> vec4f {
let last = vec3f(dims.xyz - vec3u(1u));
let surface = (position - origin.xyz) / origin.w;
let shifted = (point - origin.xyz) / origin.w;
let surface_out = any(surface < vec3f(0.0)) || any(surface > last);
let shifted_out = any(shifted < vec3f(0.0)) || any(shifted > last);
if (surface_out && shifted_out) { return vec4f(0.0); }
let coord = clamp(shifted, vec3f(0.0), last);
let base = min(vec3u(floor(coord)), max(dims.xyz, vec3u(2u)) - vec3u(2u));
var t = clamp(coord - vec3f(base), vec3f(0.0), vec3f(1.0));
for (var axis = 0u; axis < 3u; axis++) {
if (dims[axis] == 1u) { t[axis] = 0.0; }
}
let version_two = dims.w == 2u;
var color = vec3f(0.0);
var toward_luma = 0.0;
var total = 0.0;
for (var corner = 0u; corner < 8u; corner++) {
var xyz = base;
var weight = 1.0;
for (var axis = 0u; axis < 3u; axis++) {
let high = (corner & (1u << axis)) != 0u;
if (high && dims[axis] > 1u) { xyz[axis] += 1u; }
weight *= select(1.0 - t[axis], t[axis], high);
}
weight = max(weight - probe_grid.blend.z, 0.0);
if (weight == 0.0) { continue; }
let offset = words + probe_index(xyz, dims) * select(15u, 20u, version_two);
var center = origin.xyz + vec3f(xyz) * origin.w;
if (version_two) {
let last = probe_word(anchor, offset + 19u);
if (((last >> 16u) & 1u) == 0u) { continue; }
center += vec3f(unpack2x16float(probe_word(anchor, offset + 18u)), unpack2x16float(last).x) * origin.w;
let toward_probe = center - position + n * 0.0001;
let facing = clamp((dot(toward_probe / max(length(toward_probe), 0.000001), n) + 1.0) * 0.5, 0.0, 1.0);
weight *= facing * facing * facing;
if (weight == 0.0) { continue; }
let block = probe_block(anchor, offset);
let toward_point = point - center;
let distance = length(toward_point);
let direction = toward_point / max(distance, 0.000001);
var irradiance = vec3f(0.0);
var toward_irradiance = 0.0;
var mean = 0.0;
var second = 0.0;
for (var axis = 0u; axis < 3u; axis++) {
let normal_component = n[axis];
let up = normal_component >= 0.0;
let rg = unpack2x16float(select(block[axis * 4u + 2u], block[axis * 4u], up));
let b = unpack2x16float(select(block[axis * 4u + 3u], block[axis * 4u + 1u], up)).x;
irradiance += vec3f(rg, b) * normal_component * normal_component;
let toward_component = toward[axis];
let toward_up = toward_component >= 0.0;
let toward_rg = unpack2x16float(select(block[axis * 4u + 2u], block[axis * 4u], toward_up));
let toward_b = unpack2x16float(select(block[axis * 4u + 3u], block[axis * 4u + 1u], toward_up)).x;
toward_irradiance += dot(vec3f(toward_rg, toward_b), vec3f(0.2126, 0.7152, 0.0722)) * toward_component * toward_component;
let ray_component = direction[axis];
let pair = unpack2x16float(block[12u + axis]);
let depth = select(pair.y, pair.x, ray_component >= 0.0);
let ray_weight = ray_component * ray_component;
let squared = unpack2x16float(block[15u + axis]);
mean += ray_weight * depth * origin.w;
second += ray_weight * select(squared.y, squared.x, ray_component >= 0.0) * origin.w * origin.w;
}
let variance = max(second - mean * mean, origin.w * origin.w * 0.01);
let delta = max(distance - mean - origin.w * 0.1, 0.0);
let chance = variance / (variance + delta * delta);
weight *= chance * chance;
color += irradiance * weight;
toward_luma += toward_irradiance * weight;
total += weight;
continue;
}
let toward_probe = center - position + n * 0.0001;
let facing = clamp((dot(toward_probe / max(length(toward_probe), 0.000001), n) + 1.0) * 0.5, 0.0, 1.0);
weight *= facing * facing * facing;
if (weight == 0.0) { continue; }
let toward_point = point - center;
let distance = length(toward_point);
let direction = toward_point / max(distance, 0.000001);
var irradiance = vec3f(0.0);
var toward_irradiance = 0.0;
var visibility = 0.0;
for (var axis = 0u; axis < 3u; axis++) {
let normal_component = n[axis];
let normal_lobe = axis * 2u + select(1u, 0u, normal_component >= 0.0);
let rg = unpack2x16float(probe_word(anchor, offset + normal_lobe * 2u));
let b = unpack2x16float(probe_word(anchor, offset + normal_lobe * 2u + 1u)).x;
irradiance += vec3f(rg, b) * normal_component * normal_component;
let toward_component = toward[axis];
if (toward_component != 0.0) {
let toward_lobe = axis * 2u + select(1u, 0u, toward_component >= 0.0);
let toward_rg = unpack2x16float(probe_word(anchor, offset + toward_lobe * 2u));
let toward_b = unpack2x16float(probe_word(anchor, offset + toward_lobe * 2u + 1u)).x;
toward_irradiance += dot(vec3f(toward_rg, toward_b), vec3f(0.2126, 0.7152, 0.0722)) * toward_component * toward_component;
}
let ray_component = direction[axis];
let pair = unpack2x16float(probe_word(anchor, offset + 12u + axis));
let depth = select(pair.y, pair.x, ray_component >= 0.0);
let ray_weight = ray_component * ray_component;
let reach = depth + origin.w * 0.25;
visibility += ray_weight * clamp((reach - distance) / origin.w, 0.0, 1.0);
}
weight *= select(1.0, visibility, distance > 0.000001);
color += irradiance * weight;
toward_luma += toward_irradiance * weight;
total += weight;
}
if (total <= 0.000001) { return vec4f(0.0); }
*seen = toward_luma / total;
return vec4f(color / total, 1.0);
}
fn probe_local_fade(point: vec3f, local: ProbeLocal) -> f32 {
let far = local.min_spacing.xyz + vec3f(local.dims.xyz - vec3u(1u)) * local.min_spacing.w;
let inside = min(point - local.min_spacing.xyz, far - point);
return clamp(min(inside.x, min(inside.y, inside.z)) / local.min_spacing.w, 0.0, 1.0);
}
fn sample_probe_anchor(position: vec3f, normal: vec3f, anchor: u32) -> vec3f {
var unused = 0.0;
return sample_probe_anchor_toward(position, normal, vec3f(0.0), anchor, &unused);
}
fn sample_probe_anchor_toward(position: vec3f, normal: vec3f, toward: vec3f, anchor: u32, seen: ptr<function, f32>) -> vec3f {
let normal_length = length(normal);
if (normal_length < 0.000001 || normal_length != normal_length || normal_length > 1e20 || any(position != position) || any(abs(position) > vec3f(1e20))) { return probe_grid.fallback.xyz; }
let n = normal / normal_length;
let point = position + n * 0.006;
var local = vec4f(0.0);
var local_seen = 0.0;
var fade = 0.0;
let count = min(u32(probe_grid.blend.w), 4u);
for (var k = 0u; k < count; k++) {
let inner = probe_local_fade(point, probe_grid.locals[k]);
if (inner <= 0.0) { continue; }
let sampled = sample_probe_volume(position, n, point, anchor, probe_grid.locals[k].min_spacing, vec4u(probe_grid.locals[k].dims.xyz, 2u), probe_grid.locals[k].dims.w, toward, &local_seen);
if (sampled.w > 0.0) {
local = sampled;
fade = inner;
break;
}
}
if (fade >= 1.0) {
*seen = local_seen;
return local.xyz;
}
var main_seen = 0.0;
let main = sample_probe_volume(position, n, point, anchor, probe_grid.min_spacing, probe_grid.dims, 0u, toward, &main_seen);
if (main.w <= 0.0) {
if (fade > 0.0) {
*seen = local_seen;
return local.xyz;
}
return probe_grid.fallback.xyz;
}
if (fade <= 0.0) {
*seen = main_seen;
return main.xyz;
}
*seen = mix(main_seen, local_seen, fade);
return mix(main.xyz, local.xyz, fade);
}
fn probe_reflection_occlusion(grid: vec3f, reference: vec3f) -> f32 {
let threshold = probe_grid.shade.x;
if (threshold <= 0.0 || grid.x < 0.0) { return 1.0; }
let open = dot(reference, vec3f(0.2126, 0.7152, 0.0722)) * threshold;
if (!(open > 0.000001)) { return 1.0; }
return clamp(dot(grid, vec3f(0.2126, 0.7152, 0.0722)) / open, 0.0, 1.0);
}
fn sample_live_irradiance(position: vec3f, normal: vec3f) -> vec3f {
if (!use_probes || probe_grid.blend.y < 0.5) { return probe_grid.fallback.xyz; }
let lower = sample_probe_anchor(position, normal, 0u);
if (probe_grid.blend.x <= 0.0) { return lower; }
let upper = sample_probe_anchor(position, normal, 1u);
return mix(lower, upper, probe_grid.blend.x);
}
fn sample_live_irradiance_toward(position: vec3f, normal: vec3f, toward: vec3f, seen: ptr<function, f32>) -> vec3f {
if (!use_probes || probe_grid.blend.y < 0.5) { return probe_grid.fallback.xyz; }
var lower_seen = -1.0;
let lower = sample_probe_anchor_toward(position, normal, toward, 0u, &lower_seen);
if (probe_grid.blend.x <= 0.0) {
*seen = lower_seen;
return lower;
}
var upper_seen = -1.0;
let upper = sample_probe_anchor_toward(position, normal, toward, 1u, &upper_seen);
if (lower_seen >= 0.0 && upper_seen >= 0.0) {
*seen = mix(lower_seen, upper_seen, probe_grid.blend.x);
}
return mix(lower, upper, probe_grid.blend.x);
}
"#;