Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Merged by Bors] - Bloom #6397

Closed
wants to merge 33 commits into from
Closed
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
3a86a0e
add separate tonemapping and upscaling pass
jakobhellermann Dec 23, 2021
315ef6f
return rendered-to texture view as output
jakobhellermann Dec 24, 2021
cf014e8
create bind group in tonemapping/upscaling node to enable customization
jakobhellermann Dec 29, 2021
babcbb2
make hdr configurable
jakobhellermann Dec 30, 2021
21ba00d
add UpscalingPipelineKey
jakobhellermann Mar 20, 2022
08e4ff2
add bloom node
jakobhellermann Dec 24, 2021
3ab3c4f
make bloom spheres sometimes non-emissive
jakobhellermann Dec 24, 2021
c056271
Merge commit '838b318863a4d9374e16c8b46dce8be53519c88f' into bloom-no…
JMS55 Oct 26, 2022
33198fb
Small cleanup
JMS55 Oct 27, 2022
19bec71
Initial bloom shader cleanup/port
JMS55 Oct 27, 2022
57782c8
Bloom WIP
JMS55 Oct 27, 2022
cfd8ac4
Bloom fixes
JMS55 Oct 27, 2022
584575e
Fix wrong texture binding
JMS55 Oct 27, 2022
2c33c96
Document example a little more
JMS55 Oct 28, 2022
17c401d
Add intensity and reorganize
cart Nov 2, 2022
7b87364
Merge remote-tracking branch 'origin/main' into pr/JMS55/6397
cart Nov 2, 2022
fd5b01a
Add MSAA support
cart Nov 2, 2022
4584aa3
Merge pull request #1 from cart/bloom-tweaks
JMS55 Nov 2, 2022
1fd95b8
Resolve Bloom Clippy
cart Nov 2, 2022
7792070
Merge pull request #2 from cart/bloom-tweaks
JMS55 Nov 2, 2022
04346c8
support for camera_2d
DGriffin91 Nov 3, 2022
cea7545
Merge pull request #3 from DGriffin91/bloom-node-new
JMS55 Nov 3, 2022
7a17524
Bloom cleanup, move to core_pipeline
JMS55 Nov 3, 2022
8aad516
Add bloom example controls
JMS55 Nov 3, 2022
d82813b
Tweak bloom example
JMS55 Nov 3, 2022
acdf2da
Merge commit '157f2c1584a7b535b07fdb43871cab7fed643ad1' into bloom-no…
JMS55 Nov 3, 2022
feabf64
Merge commit 'e6a016458768312e72ad669e49cd082a389272a3' into bloom-no…
JMS55 Nov 3, 2022
87a5b77
Improve bloom example controls
JMS55 Nov 3, 2022
48ed761
Update crates/bevy_core_pipeline/src/bloom/mod.rs
cart Nov 3, 2022
fa80a08
Apply suggestions from code review
cart Nov 3, 2022
b84f768
Update Cargo.toml
cart Nov 3, 2022
f7fd53f
Update Cargo.toml
JMS55 Nov 4, 2022
8559e67
Add bloom example to readme
JMS55 Nov 4, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,10 @@ description = "Illustrates spot lights"
category = "3D Rendering"
wasm = true

[[example]]
name = "bloom"
path = "examples/3d/bloom.rs"

cart marked this conversation as resolved.
Show resolved Hide resolved
[[example]]
name = "load_gltf"
path = "examples/3d/load_gltf.rs"
Expand Down
131 changes: 131 additions & 0 deletions crates/bevy_pbr/src/bloom/bloom.wgsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
#import bevy_core_pipeline::fullscreen_vertex_shader

struct Uniforms {
JMS55 marked this conversation as resolved.
Show resolved Hide resolved
threshold: f32,
knee: f32,
scale: f32,
JMS55 marked this conversation as resolved.
Show resolved Hide resolved
};

@group(0) @binding(0) var org: texture_2d<f32>;
JMS55 marked this conversation as resolved.
Show resolved Hide resolved
@group(0) @binding(1) var org_sampler: sampler;
@group(0) @binding(2) var<uniform> uniforms: Uniforms;
@group(0) @binding(3) var up: texture_2d<f32>;

fn quadratic_threshold(color: vec4<f32>, threshold: f32, curve: vec3<f32>) -> vec4<f32> {
let br = max(max(color.r, color.g), color.b);

var rq: f32 = clamp(br - curve.x, 0.0, curve.y);
rq = curve.z * rq * rq;

return color * max(rq, br - threshold) / max(br, 0.0001);
}

// samples org around the supplied uv using a filter
JMS55 marked this conversation as resolved.
Show resolved Hide resolved
//
// o o o
// o o
// o o o
// o o
// o o o
//
// this is used because it has a number of advantages that
// outway the cost of 13 samples that basically boil down
JMS55 marked this conversation as resolved.
Show resolved Hide resolved
// to it looking better
//
// these advantages are outlined in a youtube video by the Cherno:
// https://www.youtube.com/watch?v=tI70-HIc5ro
JMS55 marked this conversation as resolved.
Show resolved Hide resolved
fn sample_13_tap(uv: vec2<f32>, scale: vec2<f32>) -> vec4<f32> {
let a = textureSample(org, org_sampler, uv + vec2<f32>(-1.0, -1.0) * scale);
let b = textureSample(org, org_sampler, uv + vec2<f32>(0.0, -1.0) * scale);
let c = textureSample(org, org_sampler, uv + vec2<f32>(1.0, -1.0) * scale);
let d = textureSample(org, org_sampler, uv + vec2<f32>(-0.5, -0.5) * scale);
let e = textureSample(org, org_sampler, uv + vec2<f32>(0.5, -0.5) * scale);
let f = textureSample(org, org_sampler, uv + vec2<f32>(-1.0, 0.0) * scale);
let g = textureSample(org, org_sampler, uv + vec2<f32>(0.0, 0.0) * scale);
let h = textureSample(org, org_sampler, uv + vec2<f32>(1.0, 0.0) * scale);
let i = textureSample(org, org_sampler, uv + vec2<f32>(-0.5, 0.5) * scale);
let j = textureSample(org, org_sampler, uv + vec2<f32>(0.5, 0.5) * scale);
let k = textureSample(org, org_sampler, uv + vec2<f32>(-1.0, 1.0) * scale);
let l = textureSample(org, org_sampler, uv + vec2<f32>(0.0, 1.0) * scale);
let m = textureSample(org, org_sampler, uv + vec2<f32>(1.0, 1.0) * scale);

let div = (1.0 / 4.0) * vec2<f32>(0.5, 0.125);

var o: vec4<f32> = (d + e + i + j) * div.x;
o = o + (a + b + g + f) * div.y;
o = o + (b + c + h + g) * div.y;
o = o + (f + g + l + k) * div.y;
o = o + (g + h + m + l) * div.y;

return o;
}

// samples org using a 3x3 tent filter
//
// NOTE: use a 2x2 filter for better perf, but 3x3 looks better
fn sample_3x3_tent(uv: vec2<f32>, scale: vec2<f32>) -> vec4<f32> {
let d = vec4<f32>(1.0, 1.0, -1.0, 0.0);

var s: vec4<f32> = textureSample(org, org_sampler, uv - d.xy * scale);
s = s + textureSample(org, org_sampler, uv - d.wy * scale) * 2.0;
s = s + textureSample(org, org_sampler, uv - d.zy * scale);

s = s + textureSample(org, org_sampler, uv + d.zw * scale) * 2.0;
s = s + textureSample(org, org_sampler, uv) * 4.0;
s = s + textureSample(org, org_sampler, uv + d.xw * scale) * 2.0;

s = s + textureSample(org, org_sampler, uv + d.zy * scale);
s = s + textureSample(org, org_sampler, uv + d.wy * scale) * 2.0;
s = s + textureSample(org, org_sampler, uv + d.xy * scale);

return s / 16.0;
}

@fragment
fn down_sample_pre_filter(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
let texel_size = 1.0 / vec2<f32>(textureDimensions(org));

let scale = texel_size;

let curve = vec3<f32>(
uniforms.threshold - uniforms.knee,
uniforms.knee * 2.0,
0.25 / uniforms.knee,
);

var o: vec4<f32> = sample_13_tap(uv, scale);

o = quadratic_threshold(o, uniforms.threshold, curve);
o = max(o, vec4<f32>(0.00001));

return o;
}

@fragment
fn down_sample(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
let texel_size = 1.0 / vec2<f32>(textureDimensions(org));

let scale = texel_size;

return sample_13_tap(uv, scale);
}

@fragment
fn up_sample(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
let texel_size = 1.0 / vec2<f32>(textureDimensions(org));

let up_sample = sample_3x3_tent(uv, texel_size * uniforms.scale);
var color: vec4<f32> = textureSample(up, org_sampler, uv);
color = vec4<f32>(color.rgb + up_sample.rgb, up_sample.a);

return color;
}

@fragment
fn up_sample_final(@location(0) uv: vec2<f32>) -> @location(0) vec4<f32> {
let texel_size = 1.0 / vec2<f32>(textureDimensions(org));

let up_sample = sample_3x3_tent(uv, texel_size * uniforms.scale);

return up_sample;
}
Loading