10 threshold_precomputations: vec4<f32>, 16@group(0) @binding(0) var input_texture: texture_2d<f32>; 17@group(0) @binding(1) var s: sampler; 19@group(0) @binding(2) var<uniform> uniforms: BloomUniforms; 21#ifdef FIRST_DOWNSAMPLE 23fn soft_threshold(color: vec3<f32>) -> vec3<f32> { 24 let brightness = max(color.r, max(color.g, color.b)); 25 var softness = brightness - uniforms.threshold_precomputations.y; 26 softness = clamp(softness, 0.0, uniforms.threshold_precomputations.z); 27 softness = softness * softness * uniforms.threshold_precomputations.w; 28 var contribution = max(brightness - uniforms.threshold_precomputations.x, softness); 29 contribution /= max(brightness, 0.00001); 30 return color * contribution; 36fn tonemapping_luminance(v: vec3<f32>) -> f32 { 37 return dot(v, vec3<f32>(0.2126, 0.7152, 0.0722)); 40fn rgb_to_srgb_simple(color: vec3<f32>) -> vec3<f32> { 41 return pow(color, vec3<f32>(1.0 / 2.2)); 45fn karis_average(color: vec3<f32>) -> f32 { 48 let luma = tonemapping_luminance(rgb_to_srgb_simple(color)) / 4.0; 49 return 1.0 / (1.0 + luma); 53fn sample_input_13_tap(uv: vec2<f32>) -> vec3<f32> { 54 let a = textureSample(input_texture, s, uv, vec2<i32>(-2, 2)).rgb; 55 let b = textureSample(input_texture, s, uv, vec2<i32>(0, 2)).rgb; 56 let c = textureSample(input_texture, s, uv, vec2<i32>(2, 2)).rgb; 57 let d = textureSample(input_texture, s, uv, vec2<i32>(-2, 0)).rgb; 58 let e = textureSample(input_texture, s, uv).rgb; 59 let f = textureSample(input_texture, s, uv, vec2<i32>(2, 0)).rgb; 60 let g = textureSample(input_texture, s, uv, vec2<i32>(-2, -2)).rgb; 61 let h = textureSample(input_texture, s, uv, vec2<i32>(0, -2)).rgb; 62 let i = textureSample(input_texture, s, uv, vec2<i32>(2, -2)).rgb; 63 let j = textureSample(input_texture, s, uv, vec2<i32>(-1, 1)).rgb; 64 let k = textureSample(input_texture, s, uv, vec2<i32>(1, 1)).rgb; 65 let l = textureSample(input_texture, s, uv, vec2<i32>(-1, -1)).rgb; 66 let m = textureSample(input_texture, s, uv, vec2<i32>(1, -1)).rgb; 68#ifdef FIRST_DOWNSAMPLE 77 var group0 = (a + b + d + e) * (0.125f / 4.0f); 78 var group1 = (b + c + e + f) * (0.125f / 4.0f); 79 var group2 = (d + e + g + h) * (0.125f / 4.0f); 80 var group3 = (e + f + h + i) * (0.125f / 4.0f); 81 var group4 = (j + k + l + m) * (0.5f / 4.0f); 82 group0 *= karis_average(group0); 83 group1 *= karis_average(group1); 84 group2 *= karis_average(group2); 85 group3 *= karis_average(group3); 86 group4 *= karis_average(group4); 87 return group0 + group1 + group2 + group3 + group4; 89 var sample = (a + c + g + i) * 0.03125; 90 sample += (b + d + f + h) * 0.0625; 91 sample += (e + j + k + l + m) * 0.125; 97fn sample_input_3x3_tent(uv: vec2<f32>) -> vec3<f32> { 99 let x = uniforms.uv_offset / uniforms.aspect; 100 let y = uniforms.uv_offset; 102 let a = textureSample(input_texture, s, vec2<f32>(uv.x - x, uv.y + y)).rgb; 103 let b = textureSample(input_texture, s, vec2<f32>(uv.x, uv.y + y)).rgb; 104 let c = textureSample(input_texture, s, vec2<f32>(uv.x + x, uv.y + y)).rgb; 106 let d = textureSample(input_texture, s, vec2<f32>(uv.x - x, uv.y)).rgb; 107 let e = textureSample(input_texture, s, vec2<f32>(uv.x, uv.y)).rgb; 108 let f = textureSample(input_texture, s, vec2<f32>(uv.x + x, uv.y)).rgb; 110 let g = textureSample(input_texture, s, vec2<f32>(uv.x - x, uv.y - y)).rgb; 111 let h = textureSample(input_texture, s, vec2<f32>(uv.x, uv.y - y)).rgb; 112 let i = textureSample(input_texture, s, vec2<f32>(uv.x + x, uv.y - y)).rgb; 114 var sample = e * 0.25; 115 sample += (b + d + f + h) * 0.125; 116 sample += (a + c + g + i) * 0.0625; 121#ifdef FIRST_DOWNSAMPLE 123fn downsample_first(@location(0) output_uv: vec2<f32>) -> @location(0) vec4<f32> { 124 let sample_uv = uniforms.viewport.xy + output_uv * uniforms.viewport.zw; 125 var sample = sample_input_13_tap(sample_uv); 130 sample = clamp(sample, vec3<f32>(0.0001), vec3<f32>(3.40282347E+37)); 133 sample = soft_threshold(sample); 136 return vec4<f32>(sample, 1.0); 141fn downsample(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> { 142 return vec4<f32>(sample_input_13_tap(uv), 1.0); 146fn upsample(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> { 147 return vec4<f32>(sample_input_3x3_tent(uv), 1.0);