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; 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; 35fn tonemapping_luminance(v: vec3<f32>) -> f32 { 36 return dot(v, vec3<f32>(0.2126, 0.7152, 0.0722)); 40fn karis_average(color: vec3<f32>) -> f32 { 43 let luma = tonemapping_luminance(color) / 4.0; 44 return 1.0 / (1.0 + luma); 48fn sample_input_13_tap(uv: vec2<f32>) -> vec3<f32> { 70 a = textureSample(input_texture, s, uv, vec2<i32>(-2, 2)).rgb; 71 b = textureSample(input_texture, s, uv, vec2<i32>(0, 2)).rgb; 72 c = textureSample(input_texture, s, uv, vec2<i32>(2, 2)).rgb; 73 d = textureSample(input_texture, s, uv, vec2<i32>(-2, 0)).rgb; 74 e = textureSample(input_texture, s, uv).rgb; 75 f = textureSample(input_texture, s, uv, vec2<i32>(2, 0)).rgb; 76 g = textureSample(input_texture, s, uv, vec2<i32>(-2, -2)).rgb; 77 h = textureSample(input_texture, s, uv, vec2<i32>(0, -2)).rgb; 78 i = textureSample(input_texture, s, uv, vec2<i32>(2, -2)).rgb; 79 j = textureSample(input_texture, s, uv, vec2<i32>(-1, 1)).rgb; 80 k = textureSample(input_texture, s, uv, vec2<i32>(1, 1)).rgb; 81 l = textureSample(input_texture, s, uv, vec2<i32>(-1, -1)).rgb; 82 m = textureSample(input_texture, s, uv, vec2<i32>(1, -1)).rgb; 93 let scale = uniforms.scale; 94 let ps = scale / vec2<f32>(textureDimensions(input_texture)); 98 a = textureSample(input_texture, s, uv + vec2<f32>(nl.x, pl.y)).rgb; 99 b = textureSample(input_texture, s, uv + vec2<f32>(0.00, pl.y)).rgb; 100 c = textureSample(input_texture, s, uv + vec2<f32>(pl.x, pl.y)).rgb; 101 d = textureSample(input_texture, s, uv + vec2<f32>(nl.x, 0.00)).rgb; 102 e = textureSample(input_texture, s, uv).rgb; 103 f = textureSample(input_texture, s, uv + vec2<f32>(pl.x, 0.00)).rgb; 104 g = textureSample(input_texture, s, uv + vec2<f32>(nl.x, nl.y)).rgb; 105 h = textureSample(input_texture, s, uv + vec2<f32>(0.00, nl.y)).rgb; 106 i = textureSample(input_texture, s, uv + vec2<f32>(pl.x, nl.y)).rgb; 107 j = textureSample(input_texture, s, uv + vec2<f32>(ns.x, ps.y)).rgb; 108 k = textureSample(input_texture, s, uv + vec2<f32>(ps.x, ps.y)).rgb; 109 l = textureSample(input_texture, s, uv + vec2<f32>(ns.x, ns.y)).rgb; 110 m = textureSample(input_texture, s, uv + vec2<f32>(ps.x, ns.y)).rgb; 113@if(FIRST_DOWNSAMPLE) { 122 var group0 = (a + b + d + e) * (0.125f / 4.0f); 123 var group1 = (b + c + e + f) * (0.125f / 4.0f); 124 var group2 = (d + e + g + h) * (0.125f / 4.0f); 125 var group3 = (e + f + h + i) * (0.125f / 4.0f); 126 var group4 = (j + k + l + m) * (0.5f / 4.0f); 127 group0 *= karis_average(group0); 128 group1 *= karis_average(group1); 129 group2 *= karis_average(group2); 130 group3 *= karis_average(group3); 131 group4 *= karis_average(group4); 132 return group0 + group1 + group2 + group3 + group4; 134 var sample = (a + c + g + i) * 0.03125; 135 sample += (b + d + f + h) * 0.0625; 136 sample += (e + j + k + l + m) * 0.125; 142fn sample_input_3x3_tent(uv: vec2<f32>) -> vec3<f32> { 145 let frag_size = uniforms.scale / vec2<f32>(textureDimensions(input_texture)); 149 let a = textureSample(input_texture, s, vec2<f32>(uv.x - x, uv.y + y)).rgb; 150 let b = textureSample(input_texture, s, vec2<f32>(uv.x, uv.y + y)).rgb; 151 let c = textureSample(input_texture, s, vec2<f32>(uv.x + x, uv.y + y)).rgb; 153 let d = textureSample(input_texture, s, vec2<f32>(uv.x - x, uv.y)).rgb; 154 let e = textureSample(input_texture, s, vec2<f32>(uv.x, uv.y)).rgb; 155 let f = textureSample(input_texture, s, vec2<f32>(uv.x + x, uv.y)).rgb; 157 let g = textureSample(input_texture, s, vec2<f32>(uv.x - x, uv.y - y)).rgb; 158 let h = textureSample(input_texture, s, vec2<f32>(uv.x, uv.y - y)).rgb; 159 let i = textureSample(input_texture, s, vec2<f32>(uv.x + x, uv.y - y)).rgb; 161 var sample = e * 0.25; 162 sample += (b + d + f + h) * 0.125; 163 sample += (a + c + g + i) * 0.0625; 170fn downsample_first(@location(0) output_uv: vec2<f32>) -> @location(0) vec4<f32> { 171 let sample_uv = uniforms.viewport.xy + output_uv * uniforms.viewport.zw; 172 var sample = sample_input_13_tap(sample_uv); 177 sample = clamp(sample, vec3<f32>(0.0001), vec3<f32>(3.40282347E+37)); 180 sample = soft_threshold(sample); 182 return vec4<f32>(sample, 1.0); 186fn downsample(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> { 187 return vec4<f32>(sample_input_13_tap(uv), 1.0); 191fn upsample(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> { 192 return vec4<f32>(sample_input_3x3_tent(uv), 1.0);