mirror of
https://github.com/Rezmason/matrix.git
synced 2026-04-14 12:29:30 -07:00
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:
45
shaders/wgsl/bloomBlur.wgsl
Normal file
45
shaders/wgsl/bloomBlur.wgsl
Normal 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);
|
||||
}
|
||||
31
shaders/wgsl/bloomCombine.wgsl
Normal file
31
shaders/wgsl/bloomCombine.wgsl
Normal 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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
Reference in New Issue
Block a user