Skip to content

Add a bloom example #11

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ add_executable(SDL_gpu_examples
Examples/TriangleMSAA.c
Examples/Cubemap.c
Examples/WindowResize.c
Examples/Bloom.c
)

target_include_directories(SDL_gpu_examples PRIVATE . spirv)
Expand Down
Binary file added Content/Shaders/Compiled/Bloom.vert.spv
Binary file not shown.
Binary file added Content/Shaders/Compiled/BloomDownsample.frag.spv
Binary file not shown.
Binary file added Content/Shaders/Compiled/BloomUpsample.frag.spv
Binary file not shown.
Binary file added Content/Shaders/Compiled/LerpBlend.frag.spv
Binary file not shown.
11 changes: 11 additions & 0 deletions Content/Shaders/Source/Bloom.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#version 450

layout (location = 0) in vec3 Position;
layout (location = 1) in vec2 TexCoord;
layout (location = 0) out vec2 outTexCoord;

void main()
{
outTexCoord = TexCoord;
gl_Position = vec4(Position, 1);
}
60 changes: 60 additions & 0 deletions Content/Shaders/Source/BloomDownsample.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#version 450

// This shader performs downsampling on a texture,
// as taken from the Call Of Duty method, presented at ACM Siggraph 2014.

layout (location = 0) in vec2 TexCoord;
layout (location = 0) out vec4 FragColor;
layout (set = 2, binding = 0) uniform sampler2D Sampler;

void main()
{
vec2 srcTexelSize = vec2(1.0, 1.0) / textureSize(Sampler, 0);
float x = srcTexelSize.x;
float y = srcTexelSize.y;

// Take 13 samples around current texel:
// a - b - c
// - j - k -
// d - e - f
// - l - m -
// g - h - i
// === ('e' is the current texel) ===
vec3 a = texture(Sampler, vec2(TexCoord.x - 2*x, TexCoord.y + 2*y)).rgb;
vec3 b = texture(Sampler, vec2(TexCoord.x, TexCoord.y + 2*y)).rgb;
vec3 c = texture(Sampler, vec2(TexCoord.x + 2*x, TexCoord.y + 2*y)).rgb;

vec3 d = texture(Sampler, vec2(TexCoord.x - 2*x, TexCoord.y)).rgb;
vec3 e = texture(Sampler, vec2(TexCoord.x, TexCoord.y)).rgb;
vec3 f = texture(Sampler, vec2(TexCoord.x + 2*x, TexCoord.y)).rgb;

vec3 g = texture(Sampler, vec2(TexCoord.x - 2*x, TexCoord.y - 2*y)).rgb;
vec3 h = texture(Sampler, vec2(TexCoord.x, TexCoord.y - 2*y)).rgb;
vec3 i = texture(Sampler, vec2(TexCoord.x + 2*x, TexCoord.y - 2*y)).rgb;

vec3 j = texture(Sampler, vec2(TexCoord.x - x, TexCoord.y + y)).rgb;
vec3 k = texture(Sampler, vec2(TexCoord.x + x, TexCoord.y + y)).rgb;
vec3 l = texture(Sampler, vec2(TexCoord.x - x, TexCoord.y - y)).rgb;
vec3 m = texture(Sampler, vec2(TexCoord.x + x, TexCoord.y - y)).rgb;

// Apply weighted distribution:
// 0.5 + 0.125 + 0.125 + 0.125 + 0.125 = 1
// a,b,d,e * 0.125
// b,c,e,f * 0.125
// d,e,g,h * 0.125
// e,f,h,i * 0.125
// j,k,l,m * 0.5
// This shows 5 square areas that are being sampled. But some of them overlap,
// so to have an energy preserving downsample we need to make some adjustments.
// The weights are distributed, so that the sum of j,k,l,m (e.g.)
// contribute 0.5 to the final color output. The code below is written
// to effectively yield this sum. We get:
// 0.125*5 + 0.03125*4 + 0.0625*4 = 1
vec3 color = e * 0.125;
color = e*0.125;
color += (a+c+g+i)*0.03125;
color += (b+d+f+h)*0.0625;
color += (j+k+l+m)*0.125;

FragColor = vec4(color, 0.0);
}
48 changes: 48 additions & 0 deletions Content/Shaders/Source/BloomUpsample.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#version 450

// This shader performs upsampling with blur on a texture
// as taken from the Call Of Duty method, presented at ACM Siggraph 2014.

layout (location = 0) in vec2 TexCoord;
layout (location = 0) out vec4 FragColor;
layout (set = 2, binding = 0) uniform sampler2D Sampler;
layout (set = 3, binding = 0) uniform UniformBlock
{
float FilterRadius;
};

void main()
{
// The filter kernel is applied with a radius, specified in texture
// coordinates, so that the radius will vary across mip resolutions.
float x = FilterRadius;
float y = FilterRadius;

// Take 9 samples around current texel:
// a - b - c
// d - e - f
// g - h - i
// === ('e' is the current texel) ===
vec3 a = texture(Sampler, vec2(TexCoord.x - x, TexCoord.y + y)).rgb;
vec3 b = texture(Sampler, vec2(TexCoord.x, TexCoord.y + y)).rgb;
vec3 c = texture(Sampler, vec2(TexCoord.x + x, TexCoord.y + y)).rgb;

vec3 d = texture(Sampler, vec2(TexCoord.x - x, TexCoord.y)).rgb;
vec3 e = texture(Sampler, vec2(TexCoord.x, TexCoord.y)).rgb;
vec3 f = texture(Sampler, vec2(TexCoord.x + x, TexCoord.y)).rgb;

vec3 g = texture(Sampler, vec2(TexCoord.x - x, TexCoord.y - y)).rgb;
vec3 h = texture(Sampler, vec2(TexCoord.x, TexCoord.y - y)).rgb;
vec3 i = texture(Sampler, vec2(TexCoord.x + x, TexCoord.y - y)).rgb;

// Apply weighted distribution, by using a 3x3 tent filter:
// 1 | 1 2 1 |
// -- * | 2 4 2 |
// 16 | 1 2 1 |
vec3 color = e*4.0;
color += (b+d+f+h)*2.0;
color += (a+c+g+i);
color *= 1.0 / 16.0;

FragColor = vec4(color, 1.0);
}
18 changes: 18 additions & 0 deletions Content/Shaders/Source/LerpBlend.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#version 450

layout (location = 0) in vec2 TexCoord;
layout (location = 0) out vec4 FragColor;
layout (set = 2, binding = 0) uniform sampler2D Primary;
layout (set = 2, binding = 1) uniform sampler2D Secondary;
layout (set = 3, binding = 0) uniform UniformBlock
{
float Weight;
};

void main()
{
vec4 primary = texture(Primary, TexCoord);
vec4 secondary = texture(Secondary, TexCoord);

FragColor = mix(primary, secondary, Weight);
}
Loading