Rewrote the WebGPU bloom pass based on the classic Unreal solution of blurring and combining the levels of an image pyramid. Fixed the regl bloom pass to use the downscaled blurred mipmap levels to build the first pyramid.

This commit is contained in:
Rezmason
2021-11-14 22:01:56 -08:00
parent f907c1c91b
commit b0a4acdfdb
8 changed files with 170 additions and 78 deletions

View File

@@ -0,0 +1,45 @@
let ONE_OVER_SQRT_2PI = 0.39894;
[[block]] struct Config {
bloomRadius : f32;
direction : vec2<f32>;
};
[[group(0), binding(0)]] var<uniform> config : Config;
[[group(0), binding(1)]] var linearSampler : sampler;
[[group(0), binding(2)]] var tex : texture_2d<f32>;
[[group(0), binding(3)]] var outputTex : texture_storage_2d<rgba8unorm, write>;
struct ComputeInput {
[[builtin(global_invocation_id)]] id : vec3<u32>;
};
fn gaussianPDF(x : f32) -> f32 {
return ONE_OVER_SQRT_2PI * exp( -0.5 *
( x * x ) / ( config.bloomRadius * config.bloomRadius )
) / config.bloomRadius;
}
[[stage(compute), workgroup_size(32, 1, 1)]] fn computeMain(input : ComputeInput) {
var coord = vec2<i32>(input.id.xy);
var outputSize = textureDimensions(outputTex);
if (coord.x >= outputSize.x) {
return;
}
var uv = (vec2<f32>(coord) + 0.5) / vec2<f32>(outputSize);
var uvOffset = config.direction / vec2<f32>(outputSize);
var weightSum = gaussianPDF(0.0);
var sum = textureSampleLevel( tex, linearSampler, uv, 0.0) * weightSum;
for (var x : f32 = 1.0; x < config.bloomRadius; x = x + 1.0) {
var weight = gaussianPDF(x);
sum = sum + textureSampleLevel( tex, linearSampler, uv + uvOffset * x, 0.0) * weight;
sum = sum + textureSampleLevel( tex, linearSampler, uv - uvOffset * x, 0.0) * weight;
weightSum = weightSum + weight * 2.0;
}
textureStore(outputTex, coord, sum / weightSum);
}

View File

@@ -0,0 +1,31 @@
[[block]] struct Config {
bloomStrength : f32;
pyramidHeight : f32;
};
[[group(0), binding(0)]] var<uniform> config : Config;
[[group(0), binding(1)]] var linearSampler : sampler;
[[group(0), binding(2)]] var tex : texture_2d<f32>;
[[group(0), binding(3)]] var outputTex : texture_storage_2d<rgba8unorm, write>;
struct ComputeInput {
[[builtin(global_invocation_id)]] id : vec3<u32>;
};
[[stage(compute), workgroup_size(32, 1, 1)]] fn computeMain(input : ComputeInput) {
var coord = vec2<i32>(input.id.xy);
var outputSize = textureDimensions(outputTex);
if (coord.x >= outputSize.x) {
return;
}
var uv = (vec2<f32>(coord) + 0.5) / vec2<f32>(outputSize);
var sum = vec4<f32>(0.0);
for (var i = 0.0; i < config.pyramidHeight; i = i + 1.0) {
sum = sum + (1.0 - i / config.pyramidHeight) * textureSampleLevel( tex, linearSampler, uv, i + 1.0 );
}
textureStore(outputTex, coord, sum * config.bloomStrength);
}

View File

@@ -1,37 +0,0 @@
[[block]] struct Config {
bloomStrength : f32;
direction : vec2<f32>;
};
[[group(0), binding(0)]] var<uniform> config : Config;
[[group(0), binding(1)]] var nearestSampler : sampler;
[[group(0), binding(2)]] var tex : texture_2d<f32>;
[[group(0), binding(3)]] var outputTex : texture_storage_2d<rgba8unorm, write>;
struct ComputeInput {
[[builtin(global_invocation_id)]] id : vec3<u32>;
};
[[stage(compute), workgroup_size(32, 1, 1)]] fn computeMain(input : ComputeInput) {
var coord = vec2<i32>(input.id.xy);
var outputSize = textureDimensions(outputTex);
if (coord.x >= outputSize.x) {
return;
}
var uv = (vec2<f32>(coord) + 0.5) / vec2<f32>(outputSize);
var offset = config.direction / vec2<f32>(outputSize);
var sum = vec4<f32>(0.0);
sum = sum + textureSampleLevel( tex, nearestSampler, uv + offset * 3.0, 0.0 ) * 0.006;
sum = sum + textureSampleLevel( tex, nearestSampler, uv + offset * 2.0, 0.0 ) * 0.061;
sum = sum + textureSampleLevel( tex, nearestSampler, uv + offset * 1.0, 0.0 ) * 0.242;
sum = sum + textureSampleLevel( tex, nearestSampler, uv + offset * 0.0, 0.0 ) * 0.383;
sum = sum + textureSampleLevel( tex, nearestSampler, uv + offset * -1.0, 0.0 ) * 0.242;
sum = sum + textureSampleLevel( tex, nearestSampler, uv + offset * -2.0, 0.0 ) * 0.061;
sum = sum + textureSampleLevel( tex, nearestSampler, uv + offset * -3.0, 0.0 ) * 0.006;
textureStore(outputTex, coord, sum * config.bloomStrength);
}