mirror of
https://github.com/italicsjenga/slang-shaders.git
synced 2024-11-21 23:31:30 +11:00
Add bloom based on dual filter blur (#367)
* Update CRT-1tap to v1.2 * update default param * Update default param * Add bloom based on dual filter blur Previously squashed commits: WIP:Dual filtering bloom effect Add scale level weighting; Comment out debug code; Simplify tonemap Debug:Show bloom contrib Tweak defaults; Small bugfixes Organize shaders into subfolder Refactor tonemap into separate file Tweak parameters Greatly simplify exposure to intensity mapping; Clean up Fix faster preset Change luma pass size to 1 pixel Lots of polishing Add combined presets Add docs; Refactor params a bit; Cleanup Update combined presets Rename presets for better ordering
This commit is contained in:
parent
356678ec53
commit
a6e11453ad
|
@ -7,7 +7,7 @@ scale_x0 = 1.0
|
|||
scale_y0 = 1.0
|
||||
float_framebuffer0 = true
|
||||
|
||||
shader1 = shaders/dual_filter_downsample.slang
|
||||
shader1 = shaders/dual_filter/downsample.slang
|
||||
filter_linear1 = true
|
||||
scale_type1 = source
|
||||
scale_x1 = 0.5
|
||||
|
@ -15,7 +15,7 @@ scale_y1 = 0.5
|
|||
float_framebuffer1 = true
|
||||
wrap_mode1 = mirrored_repeat
|
||||
|
||||
shader2 = shaders/dual_filter_upsample.slang
|
||||
shader2 = shaders/dual_filter/upsample.slang
|
||||
filter_linear2 = true
|
||||
scale_type2 = source
|
||||
scale_x2 = 2.0
|
||||
|
|
|
@ -7,7 +7,7 @@ scale_x0 = 1.0
|
|||
scale_y0 = 1.0
|
||||
float_framebuffer0 = true
|
||||
|
||||
shader1 = shaders/dual_filter_downsample.slang
|
||||
shader1 = shaders/dual_filter/downsample.slang
|
||||
filter_linear1 = true
|
||||
scale_type1 = source
|
||||
scale_x1 = 0.5
|
||||
|
@ -15,7 +15,7 @@ scale_y1 = 0.5
|
|||
float_framebuffer1 = true
|
||||
wrap_mode1 = mirrored_repeat
|
||||
|
||||
shader2 = shaders/dual_filter_downsample.slang
|
||||
shader2 = shaders/dual_filter/downsample.slang
|
||||
filter_linear2 = true
|
||||
scale_type2 = source
|
||||
scale_x2 = 0.5
|
||||
|
@ -23,7 +23,7 @@ scale_y2 = 0.5
|
|||
float_framebuffer2 = true
|
||||
wrap_mode2 = mirrored_repeat
|
||||
|
||||
shader3 = shaders/dual_filter_upsample.slang
|
||||
shader3 = shaders/dual_filter/upsample.slang
|
||||
filter_linear3 = true
|
||||
scale_type3 = source
|
||||
scale_x3 = 2.0
|
||||
|
@ -31,7 +31,7 @@ scale_y3 = 2.0
|
|||
float_framebuffer3 = true
|
||||
wrap_mode3 = mirrored_repeat
|
||||
|
||||
shader4 = shaders/dual_filter_upsample.slang
|
||||
shader4 = shaders/dual_filter/upsample.slang
|
||||
filter_linear4 = true
|
||||
scale_type4 = source
|
||||
scale_x4 = 2.0
|
||||
|
|
|
@ -7,7 +7,7 @@ scale_x0 = 1.0
|
|||
scale_y0 = 1.0
|
||||
float_framebuffer0 = true
|
||||
|
||||
shader1 = shaders/dual_filter_downsample.slang
|
||||
shader1 = shaders/dual_filter/downsample.slang
|
||||
filter_linear1 = true
|
||||
scale_type1 = source
|
||||
scale_x1 = 0.5
|
||||
|
@ -15,7 +15,7 @@ scale_y1 = 0.5
|
|||
float_framebuffer1 = true
|
||||
wrap_mode1 = mirrored_repeat
|
||||
|
||||
shader2 = shaders/dual_filter_downsample.slang
|
||||
shader2 = shaders/dual_filter/downsample.slang
|
||||
filter_linear2 = true
|
||||
scale_type2 = source
|
||||
scale_x2 = 0.5
|
||||
|
@ -23,7 +23,7 @@ scale_y2 = 0.5
|
|||
float_framebuffer2 = true
|
||||
wrap_mode2 = mirrored_repeat
|
||||
|
||||
shader3 = shaders/dual_filter_downsample.slang
|
||||
shader3 = shaders/dual_filter/downsample.slang
|
||||
filter_linear3 = true
|
||||
scale_type3 = source
|
||||
scale_x3 = 0.5
|
||||
|
@ -31,7 +31,7 @@ scale_y3 = 0.5
|
|||
float_framebuffer3 = true
|
||||
wrap_mode3 = mirrored_repeat
|
||||
|
||||
shader4 = shaders/dual_filter_upsample.slang
|
||||
shader4 = shaders/dual_filter/upsample.slang
|
||||
filter_linear4 = true
|
||||
scale_type4 = source
|
||||
scale_x4 = 2.0
|
||||
|
@ -39,7 +39,7 @@ scale_y4 = 2.0
|
|||
float_framebuffer4 = true
|
||||
wrap_mode4 = mirrored_repeat
|
||||
|
||||
shader5 = shaders/dual_filter_upsample.slang
|
||||
shader5 = shaders/dual_filter/upsample.slang
|
||||
filter_linear5 = true
|
||||
scale_type5 = source
|
||||
scale_x5 = 2.0
|
||||
|
@ -47,7 +47,7 @@ scale_y5 = 2.0
|
|||
float_framebuffer5 = true
|
||||
wrap_mode5 = mirrored_repeat
|
||||
|
||||
shader6 = shaders/dual_filter_upsample.slang
|
||||
shader6 = shaders/dual_filter/upsample.slang
|
||||
filter_linear6 = true
|
||||
scale_type6 = source
|
||||
scale_x6 = 2.0
|
||||
|
|
187
blurs/dual_filter_bloom.slangp
Normal file
187
blurs/dual_filter_bloom.slangp
Normal file
|
@ -0,0 +1,187 @@
|
|||
shaders = 24
|
||||
|
||||
parameters = "BLUR_RADIUS"
|
||||
BLUR_RADIUS = 2.0
|
||||
|
||||
shader0 = shaders/kawase/linearize.slang
|
||||
scale_type0 = source
|
||||
scale0 = 1.0
|
||||
float_framebuffer0 = true
|
||||
alias0 = "Input"
|
||||
|
||||
|
||||
shader1 = shaders/dual_filter/downsample_bloom.slang
|
||||
filter_linear1 = true
|
||||
scale_type1 = viewport
|
||||
scale1 = 0.7
|
||||
float_framebuffer1 = true
|
||||
wrap_mode1 = mirrored_repeat
|
||||
|
||||
shader2 = shaders/dual_filter/upsample.slang
|
||||
filter_linear2 = true
|
||||
scale_type2 = source
|
||||
scale2 = 1.0
|
||||
float_framebuffer2 = true
|
||||
wrap_mode2 = mirrored_repeat
|
||||
|
||||
shader3 = shaders/dual_filter/downsample.slang
|
||||
filter_linear3 = true
|
||||
scale_type3 = source
|
||||
scale3 = 0.5
|
||||
float_framebuffer3 = true
|
||||
wrap_mode3 = mirrored_repeat
|
||||
|
||||
shader4 = shaders/dual_filter/upsample.slang
|
||||
filter_linear4 = true
|
||||
scale_type4 = source
|
||||
scale4 = 2.0
|
||||
float_framebuffer4 = true
|
||||
wrap_mode4 = mirrored_repeat
|
||||
alias4 = "Scale1"
|
||||
|
||||
|
||||
shader5 = shaders/dual_filter/downsample.slang
|
||||
filter_linear5 = true
|
||||
scale_type5 = source
|
||||
scale5 = 0.5
|
||||
float_framebuffer5 = true
|
||||
wrap_mode5 = mirrored_repeat
|
||||
|
||||
shader6 = shaders/dual_filter/downsample.slang
|
||||
filter_linear6 = true
|
||||
scale_type6 = source
|
||||
scale6 = 0.5
|
||||
float_framebuffer6 = true
|
||||
wrap_mode6 = mirrored_repeat
|
||||
|
||||
shader7 = shaders/dual_filter/upsample.slang
|
||||
filter_linear7 = true
|
||||
scale_type7 = source
|
||||
scale7 = 2.0
|
||||
float_framebuffer7 = true
|
||||
wrap_mode7 = mirrored_repeat
|
||||
alias7 = "Scale2"
|
||||
|
||||
|
||||
shader8 = shaders/dual_filter/downsample.slang
|
||||
filter_linear8 = true
|
||||
scale_type8 = source
|
||||
scale8 = 0.5
|
||||
float_framebuffer8 = true
|
||||
wrap_mode8 = mirrored_repeat
|
||||
|
||||
shader9 = shaders/dual_filter/downsample.slang
|
||||
filter_linear9 = true
|
||||
scale_type9 = source
|
||||
scale9 = 0.5
|
||||
float_framebuffer9 = true
|
||||
wrap_mode9 = mirrored_repeat
|
||||
|
||||
shader10 = shaders/dual_filter/upsample.slang
|
||||
filter_linear10 = true
|
||||
scale_type10 = source
|
||||
scale10 = 2.0
|
||||
float_framebuffer10 = true
|
||||
wrap_mode10 = mirrored_repeat
|
||||
alias10 = "Scale3"
|
||||
|
||||
|
||||
shader11 = shaders/dual_filter/downsample.slang
|
||||
filter_linear11 = true
|
||||
scale_type11 = source
|
||||
scale11 = 0.5
|
||||
float_framebuffer11 = true
|
||||
wrap_mode11 = mirrored_repeat
|
||||
|
||||
shader12 = shaders/dual_filter/downsample.slang
|
||||
filter_linear12 = true
|
||||
scale_type12 = source
|
||||
scale12 = 0.5
|
||||
float_framebuffer12 = true
|
||||
wrap_mode12 = mirrored_repeat
|
||||
|
||||
shader13 = shaders/dual_filter/upsample.slang
|
||||
filter_linear13 = true
|
||||
scale_type13 = source
|
||||
scale13 = 2.0
|
||||
float_framebuffer13 = true
|
||||
wrap_mode13 = mirrored_repeat
|
||||
alias13 = "Scale4"
|
||||
|
||||
|
||||
shader14 = shaders/dual_filter/downsample.slang
|
||||
filter_linear14 = true
|
||||
scale_type14 = source
|
||||
scale14 = 0.5
|
||||
float_framebuffer14 = true
|
||||
wrap_mode14 = mirrored_repeat
|
||||
|
||||
shader15 = shaders/dual_filter/downsample.slang
|
||||
filter_linear15 = true
|
||||
scale_type15 = source
|
||||
scale15 = 0.5
|
||||
float_framebuffer15 = true
|
||||
wrap_mode15 = mirrored_repeat
|
||||
|
||||
shader16 = shaders/dual_filter/upsample.slang
|
||||
filter_linear16 = true
|
||||
scale_type16 = source
|
||||
scale16 = 2.0
|
||||
float_framebuffer16 = true
|
||||
wrap_mode16 = mirrored_repeat
|
||||
alias16 = "Scale5"
|
||||
|
||||
|
||||
shader17 = shaders/dual_filter/downsample.slang
|
||||
filter_linear17 = true
|
||||
scale_type17 = source
|
||||
scale17 = 0.5
|
||||
float_framebuffer17 = true
|
||||
wrap_mode17 = mirrored_repeat
|
||||
|
||||
shader18 = shaders/dual_filter/downsample.slang
|
||||
filter_linear18 = true
|
||||
scale_type18 = source
|
||||
scale18 = 0.5
|
||||
float_framebuffer18 = true
|
||||
wrap_mode18 = mirrored_repeat
|
||||
|
||||
shader19 = shaders/dual_filter/upsample.slang
|
||||
filter_linear19 = true
|
||||
scale_type19 = source
|
||||
scale19 = 2.0
|
||||
float_framebuffer19 = true
|
||||
wrap_mode19 = mirrored_repeat
|
||||
alias19 = "Scale6"
|
||||
|
||||
|
||||
shader20 = shaders/dual_filter/naive_resample.slang
|
||||
filter_linear20 = true
|
||||
scale_type20 = absolute
|
||||
scale_x20 = 128
|
||||
scale_y20 = 128
|
||||
float_framebuffer20 = true
|
||||
wrap_mode20 = mirrored_repeat
|
||||
|
||||
shader21 = shaders/dual_filter/moving_avg.slang
|
||||
filter_linear21 = true
|
||||
scale_type21 = absolute
|
||||
scale_x21 = 2
|
||||
scale_y21 = 2
|
||||
float_framebuffer21 = true
|
||||
mipmap_input21 = true
|
||||
alias21 = "MovingAverage"
|
||||
|
||||
|
||||
shader22 = shaders/dual_filter/bloom_blend.slang
|
||||
filter_linear22 = true
|
||||
scale_type22 = viewport
|
||||
scale22 = 1.0
|
||||
float_framebuffer22 = true
|
||||
|
||||
|
||||
shader23 = shaders/kawase/delinearize.slang
|
||||
filter_linear23 = true
|
||||
scale_type23 = viewport
|
||||
scal23 = 1.0
|
||||
float_framebuffer23 = true
|
138
blurs/dual_filter_bloom_fast.slangp
Normal file
138
blurs/dual_filter_bloom_fast.slangp
Normal file
|
@ -0,0 +1,138 @@
|
|||
shaders = 18
|
||||
|
||||
shader0 = shaders/kawase/linearize.slang
|
||||
scale_type0 = source
|
||||
scale0 = 1.0
|
||||
float_framebuffer0 = true
|
||||
alias0 = "Input"
|
||||
|
||||
|
||||
shader1 = shaders/dual_filter/downsample_bloom.slang
|
||||
filter_linear1 = true
|
||||
scale_type1 = viewport
|
||||
scale1 = 0.4
|
||||
float_framebuffer1 = true
|
||||
wrap_mode1 = mirrored_repeat
|
||||
|
||||
shader2 = shaders/dual_filter/upsample.slang
|
||||
filter_linear2 = true
|
||||
scale_type2 = source
|
||||
scale2 = 1.0
|
||||
float_framebuffer2 = true
|
||||
wrap_mode2 = mirrored_repeat
|
||||
|
||||
shader3 = shaders/dual_filter/downsample.slang
|
||||
filter_linear3 = true
|
||||
scale_type3 = source
|
||||
scale3 = 0.5
|
||||
float_framebuffer3 = true
|
||||
wrap_mode3 = mirrored_repeat
|
||||
|
||||
shader4 = shaders/dual_filter/upsample.slang
|
||||
filter_linear4 = true
|
||||
scale_type4 = source
|
||||
scale4 = 2.0
|
||||
float_framebuffer4 = true
|
||||
wrap_mode4 = mirrored_repeat
|
||||
alias4 = "Scale1"
|
||||
|
||||
|
||||
shader5 = shaders/dual_filter/downsample.slang
|
||||
filter_linear5 = true
|
||||
scale_type5 = source
|
||||
scale5 = 0.5
|
||||
float_framebuffer5 = true
|
||||
wrap_mode5 = mirrored_repeat
|
||||
|
||||
shader6 = shaders/dual_filter/downsample.slang
|
||||
filter_linear6 = true
|
||||
scale_type6 = source
|
||||
scale6 = 0.5
|
||||
float_framebuffer6 = true
|
||||
wrap_mode6 = mirrored_repeat
|
||||
|
||||
shader7 = shaders/dual_filter/upsample.slang
|
||||
filter_linear7 = true
|
||||
scale_type7 = source
|
||||
scale7 = 2.0
|
||||
float_framebuffer7 = true
|
||||
wrap_mode7 = mirrored_repeat
|
||||
alias7 = "Scale2"
|
||||
|
||||
|
||||
shader8 = shaders/dual_filter/downsample.slang
|
||||
filter_linear8 = true
|
||||
scale_type8 = source
|
||||
scale8 = 0.5
|
||||
float_framebuffer8 = true
|
||||
wrap_mode8 = mirrored_repeat
|
||||
|
||||
shader9 = shaders/dual_filter/downsample.slang
|
||||
filter_linear9 = true
|
||||
scale_type9 = source
|
||||
scale9 = 0.5
|
||||
float_framebuffer9 = true
|
||||
wrap_mode9 = mirrored_repeat
|
||||
|
||||
shader10 = shaders/dual_filter/upsample.slang
|
||||
filter_linear10 = true
|
||||
scale_type10 = source
|
||||
scale10 = 2.0
|
||||
float_framebuffer10 = true
|
||||
wrap_mode10 = mirrored_repeat
|
||||
alias10 = "Scale3"
|
||||
|
||||
|
||||
shader11 = shaders/dual_filter/downsample.slang
|
||||
filter_linear11 = true
|
||||
scale_type11 = source
|
||||
scale11 = 0.5
|
||||
float_framebuffer11 = true
|
||||
wrap_mode11 = mirrored_repeat
|
||||
|
||||
shader12 = shaders/dual_filter/downsample.slang
|
||||
filter_linear12 = true
|
||||
scale_type12 = source
|
||||
scale12 = 0.5
|
||||
float_framebuffer12 = true
|
||||
wrap_mode12 = mirrored_repeat
|
||||
|
||||
shader13 = shaders/dual_filter/upsample.slang
|
||||
filter_linear13 = true
|
||||
scale_type13 = source
|
||||
scale13 = 2.0
|
||||
float_framebuffer13 = true
|
||||
wrap_mode13 = mirrored_repeat
|
||||
alias13 = "Scale4"
|
||||
|
||||
|
||||
shader14 = shaders/dual_filter/naive_resample.slang
|
||||
filter_linear14 = true
|
||||
scale_type14 = absolute
|
||||
scale_x14 = 64
|
||||
scale_y14 = 64
|
||||
float_framebuffer14 = true
|
||||
wrap_mode14 = mirrored_repeat
|
||||
|
||||
shader15 = shaders/dual_filter/moving_avg.slang
|
||||
filter_linear15 = true
|
||||
scale_type15 = absolute
|
||||
scale_x15 = 2
|
||||
scale_y15 = 2
|
||||
float_framebuffer15 = true
|
||||
mipmap_input15 = true
|
||||
alias15 = "MovingAverage"
|
||||
|
||||
|
||||
shader16 = shaders/dual_filter/bloom_blend_fast.slang
|
||||
filter_linear16 = true
|
||||
scale_type16 = viewport
|
||||
scale16 = 1.0
|
||||
float_framebuffer16 = true
|
||||
|
||||
|
||||
shader17 = shaders/kawase/delinearize.slang
|
||||
filter_linear17 = true
|
||||
scale_type17 = viewport
|
||||
scal17 = 1.0
|
||||
float_framebuffer17 = true
|
65
blurs/dual_filter_bloom_fastest.slangp
Normal file
65
blurs/dual_filter_bloom_fastest.slangp
Normal file
|
@ -0,0 +1,65 @@
|
|||
shaders = 8
|
||||
|
||||
parameters = "MIN_EXP_INTENSITY"
|
||||
MIN_EXP_INTENSITY = 0.45
|
||||
|
||||
shader0 = shaders/kawase/linearize.slang
|
||||
scale_type0 = source
|
||||
scale0 = 1.0
|
||||
float_framebuffer0 = true
|
||||
alias0 = "Input"
|
||||
|
||||
shader1 = shaders/dual_filter/downsample_bloom.slang
|
||||
filter_linear1 = false
|
||||
scale_type1 = source
|
||||
scale1 = 0.5
|
||||
float_framebuffer1 = true
|
||||
wrap_mode1 = mirrored_repeat
|
||||
alias1 = "Downsample1"
|
||||
|
||||
shader2 = shaders/dual_filter/downsample.slang
|
||||
filter_linear2 = true
|
||||
scale_type2 = source
|
||||
scale2 = 0.5
|
||||
float_framebuffer2 = true
|
||||
wrap_mode2 = mirrored_repeat
|
||||
alias2 = "Downsample2"
|
||||
|
||||
shader3 = shaders/dual_filter/upsample.slang
|
||||
filter_linear3 = true
|
||||
scale_type3 = source
|
||||
scale3 = 2.0
|
||||
float_framebuffer3 = true
|
||||
wrap_mode3 = mirrored_repeat
|
||||
alias3 = "Upsample"
|
||||
|
||||
shader4 = shaders/dual_filter/naive_resample.slang
|
||||
filter_linear4 = true
|
||||
scale_type4 = absolute
|
||||
scale_x4 = 64
|
||||
scale_y4 = 64
|
||||
float_framebuffer4 = true
|
||||
|
||||
shader5 = shaders/dual_filter/moving_avg.slang
|
||||
filter_linear5 = true
|
||||
scale_type5 = absolute
|
||||
scale_x5 = 2
|
||||
scale_y5 = 2
|
||||
float_framebuffer5 = true
|
||||
wrap_mode5 = mirrored_repeat
|
||||
mipmap_input5 = true
|
||||
alias5 = "MovingAverage"
|
||||
|
||||
shader6 = shaders/dual_filter/bloom_blend_fastest.slang
|
||||
filter_linear6 = true
|
||||
scale_type6 = viewport
|
||||
scale6 = 1.0
|
||||
wrap_mode6 = mirrored_repeat
|
||||
float_framebuffer6 = true
|
||||
|
||||
shader7 = shaders/kawase/delinearize.slang
|
||||
filter_linear7 = false
|
||||
scale_type7 = viewport
|
||||
scale7 = 1.0
|
||||
float_framebuffer7 = true
|
||||
|
108
blurs/shaders/dual_filter/bloom_blend.slang
Normal file
108
blurs/shaders/dual_filter/bloom_blend.slang
Normal file
|
@ -0,0 +1,108 @@
|
|||
#version 450
|
||||
|
||||
// See dual_filter.slang for copyright and other information.
|
||||
|
||||
#include "dual_filter.slang"
|
||||
#include "parameters.slang"
|
||||
#include "parameters_bloom.slang"
|
||||
#include "tonemapping.slang"
|
||||
|
||||
#pragma parameter SCALE_EMPH "Bloom scale emphasis" 1.0 0.0 5.0 0.1
|
||||
#pragma parameter SCALE_SPREAD "Bloom scale spread" 5.0 0.5 15.0 0.5
|
||||
#pragma parameter DEBUG_EXPOSURE_GRAPH "Debug overlay: Exposure graph" 0.0 0.0 1.0 1.0
|
||||
|
||||
layout(push_constant) uniform Push {
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
vec4 InputSize;
|
||||
uint FrameCount;
|
||||
float MIN_EXP_INTENSITY;
|
||||
float EYE_ADAPTION;
|
||||
float MIN_EXP;
|
||||
float MAX_EXP;
|
||||
float SCALE_EMPH;
|
||||
float SCALE_SPREAD;
|
||||
float DEBUG_EXPOSURE_GRAPH;
|
||||
}
|
||||
param;
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO {
|
||||
mat4 MVP;
|
||||
}
|
||||
global;
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
layout(set = 0, binding = 3) uniform sampler2D Input;
|
||||
layout(set = 0, binding = 4) uniform sampler2D MovingAverage;
|
||||
layout(set = 0, binding = 5) uniform sampler2D Scale1;
|
||||
layout(set = 0, binding = 6) uniform sampler2D Scale2;
|
||||
layout(set = 0, binding = 7) uniform sampler2D Scale3;
|
||||
layout(set = 0, binding = 8) uniform sampler2D Scale4;
|
||||
layout(set = 0, binding = 9) uniform sampler2D Scale5;
|
||||
layout(set = 0, binding = 10) uniform sampler2D Scale6;
|
||||
|
||||
float scale_gauss(float x) {
|
||||
const float dx = x - param.SCALE_EMPH;
|
||||
return exp(-dx * dx / (2.0 * param.SCALE_SPREAD * param.SCALE_SPREAD));
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Weigh the different scale levels.
|
||||
const float w1 = scale_gauss(0.0);
|
||||
const float w2 = scale_gauss(1.0);
|
||||
const float w3 = scale_gauss(2.0);
|
||||
const float w4 = scale_gauss(3.0);
|
||||
const float w5 = scale_gauss(4.0);
|
||||
const float w6 = scale_gauss(5.0);
|
||||
vec3 bloom = w1 * texture(Scale1, vTexCoord).rgb + //
|
||||
w2 * texture(Scale2, vTexCoord).rgb + //
|
||||
w3 * texture(Scale3, vTexCoord).rgb + //
|
||||
w4 * texture(Scale4, vTexCoord).rgb + //
|
||||
w5 * texture(Scale5, vTexCoord).rgb + //
|
||||
w6 * texture(Scale6, vTexCoord).rgb / (w1 + w2 + w3 + w4 + w5 + w6);
|
||||
|
||||
// Moving average luminance sampled from respective pass.
|
||||
const vec3 ambient = texture(MovingAverage, vec2(0.5)).rgb;
|
||||
bloom =
|
||||
tonemap(bloom * ambient_to_intensity(ambient, param.MIN_EXP_INTENSITY,
|
||||
param.MIN_EXP_INTENSITY * (1.0 - param.EYE_ADAPTION),
|
||||
param.MIN_EXP, param.MAX_EXP));
|
||||
|
||||
const vec2 sharp_coord = (floor(vTexCoord * param.InputSize.xy) + 0.5) * param.InputSize.zw;
|
||||
FragColor = vec4(blend_screen(bloom, texture(Input, sharp_coord).rgb), 1.0);
|
||||
|
||||
if (param.DEBUG_EXPOSURE_GRAPH > 0.5) {
|
||||
// Debug output.
|
||||
// This is manually copied from tonemapping code, need to maintain here if things change.
|
||||
float exposure = sqrt(dot(vec3(0.30, 0.59, 0.11), ambient));
|
||||
float mapped_exp = ambient_to_intensity(
|
||||
ambient, param.MIN_EXP_INTENSITY, param.MIN_EXP_INTENSITY * (1.0 - param.EYE_ADAPTION),
|
||||
param.MIN_EXP, param.MAX_EXP);
|
||||
const float graph_x = vTexCoord.x * vTexCoord.x;
|
||||
float graph_y =
|
||||
mix(param.MIN_EXP_INTENSITY, param.MIN_EXP_INTENSITY * (1.0 - param.EYE_ADAPTION),
|
||||
smoothstep(param.MIN_EXP, param.MAX_EXP, sqrt(graph_x)));
|
||||
if (abs(1.0 - vTexCoord.y - graph_y) < 0.01) {
|
||||
FragColor = vec4(0.0, 0.0, 1.0, 1.0);
|
||||
}
|
||||
const float dx = vTexCoord.x - exposure;
|
||||
const float dy = 1.0 - vTexCoord.y - mapped_exp;
|
||||
if (sqrt(dx * dx + dy * dy) < 0.02) {
|
||||
FragColor = vec4(0.2, 0.2, 1.0, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
79
blurs/shaders/dual_filter/bloom_blend_fast.slang
Normal file
79
blurs/shaders/dual_filter/bloom_blend_fast.slang
Normal file
|
@ -0,0 +1,79 @@
|
|||
#version 450
|
||||
|
||||
// See dual_filter.slang for copyright and other information.
|
||||
|
||||
#include "dual_filter.slang"
|
||||
#include "parameters.slang"
|
||||
#include "parameters_bloom.slang"
|
||||
#include "tonemapping.slang"
|
||||
|
||||
#pragma parameter SCALE_EMPH "Bloom scale emphasis" 0.0 0.0 3.0 0.1
|
||||
#pragma parameter SCALE_SPREAD "Bloom scale spread" 4.0 0.5 10.0 0.5
|
||||
|
||||
layout(push_constant) uniform Push {
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
vec4 InputSize;
|
||||
uint FrameCount;
|
||||
float MIN_EXP_INTENSITY;
|
||||
float EYE_ADAPTION;
|
||||
float MIN_EXP;
|
||||
float MAX_EXP;
|
||||
float SCALE_EMPH;
|
||||
float SCALE_SPREAD;
|
||||
}
|
||||
param;
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO {
|
||||
mat4 MVP;
|
||||
}
|
||||
global;
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
layout(set = 0, binding = 3) uniform sampler2D Input;
|
||||
layout(set = 0, binding = 4) uniform sampler2D MovingAverage;
|
||||
layout(set = 0, binding = 5) uniform sampler2D Scale1;
|
||||
layout(set = 0, binding = 6) uniform sampler2D Scale2;
|
||||
layout(set = 0, binding = 7) uniform sampler2D Scale3;
|
||||
layout(set = 0, binding = 8) uniform sampler2D Scale4;
|
||||
|
||||
float scale_gauss(float x) {
|
||||
const float dx = x - param.SCALE_EMPH;
|
||||
return exp(-dx * dx / (2.0 * param.SCALE_SPREAD * param.SCALE_SPREAD));
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Weigh the different scale levels.
|
||||
const float w1 = scale_gauss(0.0);
|
||||
const float w2 = scale_gauss(1.0);
|
||||
const float w3 = scale_gauss(2.0);
|
||||
const float w4 = scale_gauss(3.0);
|
||||
vec3 bloom = w1 * texture(Scale1, vTexCoord).rgb + //
|
||||
w2 * texture(Scale2, vTexCoord).rgb + //
|
||||
w3 * texture(Scale3, vTexCoord).rgb + //
|
||||
w4 * texture(Scale4, vTexCoord).rgb / (w1 + w2 + w3 + w4);
|
||||
|
||||
// Moving average luminance sampled from respective pass.
|
||||
const vec3 ambient = texture(MovingAverage, vec2(0.5)).rgb;
|
||||
bloom =
|
||||
tonemap(bloom * ambient_to_intensity(ambient, param.MIN_EXP_INTENSITY,
|
||||
param.MIN_EXP_INTENSITY * (1.0 - param.EYE_ADAPTION),
|
||||
param.MIN_EXP, param.MAX_EXP));
|
||||
|
||||
const vec2 sharp_coord = (floor(vTexCoord * param.InputSize.xy) + 0.5) * param.InputSize.zw;
|
||||
FragColor = vec4(blend_screen(bloom, texture(Input, sharp_coord).rgb), 1.0);
|
||||
}
|
63
blurs/shaders/dual_filter/bloom_blend_fastest.slang
Normal file
63
blurs/shaders/dual_filter/bloom_blend_fastest.slang
Normal file
|
@ -0,0 +1,63 @@
|
|||
#version 450
|
||||
|
||||
// See dual_filter.slang for copyright and other information.
|
||||
|
||||
#include "dual_filter.slang"
|
||||
#include "parameters.slang"
|
||||
#include "parameters_bloom.slang"
|
||||
#include "tonemapping.slang"
|
||||
|
||||
layout(push_constant) uniform Push {
|
||||
vec4 InputSize;
|
||||
vec4 Downsample1Size;
|
||||
vec4 Downsample2Size;
|
||||
vec4 UpsampleSize;
|
||||
float BLUR_RADIUS;
|
||||
float MIN_EXP_INTENSITY;
|
||||
float EYE_ADAPTION;
|
||||
float MIN_EXP;
|
||||
float MAX_EXP;
|
||||
}
|
||||
param;
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO {
|
||||
mat4 MVP;
|
||||
}
|
||||
global;
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
layout(set = 0, binding = 3) uniform sampler2D Input;
|
||||
layout(set = 0, binding = 4) uniform sampler2D Downsample1;
|
||||
layout(set = 0, binding = 5) uniform sampler2D Downsample2;
|
||||
layout(set = 0, binding = 6) uniform sampler2D Upsample;
|
||||
layout(set = 0, binding = 7) uniform sampler2D MovingAverage;
|
||||
|
||||
void main() {
|
||||
const vec3 ambient = texture(MovingAverage, vec2(0.5)).rgb;
|
||||
// Hack: "Fastest" bloom appears relatively less intense compared to the regular preset.
|
||||
// Using an unnormalized value achieves about equal intensity.
|
||||
vec3 bloom =
|
||||
3.0 * upsample(Downsample1, vTexCoord, 0.5 * param.Downsample1Size.zw * param.BLUR_RADIUS) +
|
||||
1.0 * upsample(Downsample2, vTexCoord, 0.5 * param.Downsample2Size.zw * param.BLUR_RADIUS) +
|
||||
3.0 * upsample(Upsample, vTexCoord, 0.5 * param.UpsampleSize.zw * param.BLUR_RADIUS);
|
||||
bloom =
|
||||
tonemap(bloom * ambient_to_intensity(ambient, param.MIN_EXP_INTENSITY,
|
||||
param.MIN_EXP_INTENSITY * (1.0 - param.EYE_ADAPTION),
|
||||
param.MIN_EXP, param.MAX_EXP));
|
||||
|
||||
const vec2 sharp_coord = (floor(vTexCoord * param.InputSize.xy) + 0.5) * param.InputSize.zw;
|
||||
FragColor = vec4(blend_screen(bloom, texture(Input, sharp_coord).rgb), 1.0);
|
||||
}
|
|
@ -1,15 +1,16 @@
|
|||
#version 450
|
||||
|
||||
// See dual_filter_parameters.slang for copyright and other information.
|
||||
// See dual_filter.slang for copyright and other information.
|
||||
|
||||
#include "dual_filter_parameters.slang"
|
||||
#include "dual_filter.slang"
|
||||
#include "parameters.slang"
|
||||
|
||||
layout(push_constant) uniform Push {
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
float BLUR_STRENGTH;
|
||||
float BLUR_RADIUS;
|
||||
}
|
||||
param;
|
||||
|
||||
|
@ -34,11 +35,6 @@ layout(location = 0) out vec4 FragColor;
|
|||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
void main() {
|
||||
const vec2 halfpixel = 0.5 * param.SourceSize.zw * param.BLUR_STRENGTH;
|
||||
vec3 sum = texture(Source, vTexCoord).rgb * 4.0;
|
||||
sum += texture(Source, vTexCoord - halfpixel).rgb;
|
||||
sum += texture(Source, vTexCoord + halfpixel).rgb;
|
||||
sum += texture(Source, vTexCoord + vec2(halfpixel.x, -halfpixel.y)).rgb;
|
||||
sum += texture(Source, vTexCoord - vec2(halfpixel.x, -halfpixel.y)).rgb;
|
||||
FragColor = vec4(sum * 0.125, 1.0);
|
||||
const vec2 offset = param.SourceSize.zw * param.BLUR_RADIUS;
|
||||
FragColor = vec4(downsample(Source, vTexCoord, offset), 1.0);
|
||||
}
|
44
blurs/shaders/dual_filter/downsample_bloom.slang
Normal file
44
blurs/shaders/dual_filter/downsample_bloom.slang
Normal file
|
@ -0,0 +1,44 @@
|
|||
#version 450
|
||||
|
||||
// See dual_filter.slang for copyright and other information.
|
||||
|
||||
#include "dual_filter.slang"
|
||||
#include "parameters.slang"
|
||||
#include "parameters_bloom.slang"
|
||||
|
||||
layout(push_constant) uniform Push {
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
float BLUR_RADIUS;
|
||||
float BLOOM_THRESHOLD;
|
||||
}
|
||||
param;
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO {
|
||||
mat4 MVP;
|
||||
}
|
||||
global;
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
void main() {
|
||||
// Use the output pixel size as reference here to be more robust against different bloom
|
||||
// configurations.
|
||||
const vec2 offset = 0.5 * param.OutputSize.zw * param.BLUR_RADIUS;
|
||||
FragColor = vec4(pow(downsample(Source, vTexCoord, offset), vec3(param.BLOOM_THRESHOLD)), 1.0);
|
||||
}
|
57
blurs/shaders/dual_filter/dual_filter.slang
Normal file
57
blurs/shaders/dual_filter/dual_filter.slang
Normal file
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
Dual Filter Blur & Bloom v1.1 by fishku
|
||||
Copyright (C) 2023
|
||||
Public domain license (CC0)
|
||||
|
||||
The dual filter blur implementation follows the notes of the SIGGRAPH 2015 talk here:
|
||||
https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-20-66/siggraph2015_2D00_mmg_2D00_marius_2D00_notes.pdf
|
||||
Dual filtering is a fast large-radius blur that approximates a Gaussian blur. It is closely
|
||||
related to the popular blur filter by Kawase, but runs faster at equal quality.
|
||||
|
||||
How it works: Any number of downsampling passes are chained with the same number of upsampling
|
||||
passes in an hourglass configuration. Both types of resampling passes exploit bilinear
|
||||
interpolation with carefully chosen coordinates and weights to produce a smooth output.
|
||||
There are just 5 + 8 = 13 texture samples per combined down- and upsampling pass.
|
||||
The effective blur radius increases with the number of passes.
|
||||
|
||||
This implementation adds a configurable blur strength which can diminish or accentuate the
|
||||
effect compared to the reference implementation, equivalent to strength 1.0.
|
||||
A blur strength above 3.0 may lead to artifacts, especially on presets with fewer passes.
|
||||
|
||||
The bloom filter applies a thresholding operation, then blurs the input to varying degrees.
|
||||
The scene luminance is estimated using a feedback pass with variable update speed.
|
||||
The final pass screen blends a tonemapped bloom value with the original input, with the bloom
|
||||
intensity controlled by the scene luminance (a.k.a. eye adaption).
|
||||
|
||||
Changelog:
|
||||
v1.1: Added bloom functionality.
|
||||
v1.0: Initial release.
|
||||
*/
|
||||
|
||||
vec3 downsample(sampler2D tex, vec2 coord, vec2 offset) {
|
||||
// The offset should be 1 source pixel size which equals 0.5 output pixel sizes in the default
|
||||
// configuration.
|
||||
return (texture(tex, coord - offset).rgb + //
|
||||
texture(tex, coord + vec2(offset.x, -offset.y)).rgb + //
|
||||
texture(tex, coord).rgb * 4.0 + //
|
||||
texture(tex, coord + offset).rgb + //
|
||||
texture(tex, coord - vec2(offset.x, -offset.y)).rgb) *
|
||||
0.125;
|
||||
}
|
||||
|
||||
vec3 upsample(sampler2D tex, vec2 coord, vec2 offset) {
|
||||
// The offset should be 0.5 source pixel sizes which equals 1 output pixel size in the default
|
||||
// configuration.
|
||||
return (texture(tex, coord + vec2(0.0, -offset.y * 2.0)).rgb +
|
||||
(texture(tex, coord + vec2(-offset.x, -offset.y)).rgb +
|
||||
texture(tex, coord + vec2(offset.x, -offset.y)).rgb) *
|
||||
2.0 +
|
||||
texture(tex, coord + vec2(-offset.x * 2.0, 0.0)).rgb +
|
||||
texture(tex, coord + vec2(offset.x * 2.0, 0.0)).rgb +
|
||||
(texture(tex, coord + vec2(-offset.x, offset.y)).rgb +
|
||||
texture(tex, coord + vec2(offset.x, offset.y)).rgb) *
|
||||
2.0 +
|
||||
texture(tex, coord + vec2(0.0, offset.y * 2.0)).rgb) /
|
||||
12.0;
|
||||
}
|
||||
|
42
blurs/shaders/dual_filter/moving_avg.slang
Normal file
42
blurs/shaders/dual_filter/moving_avg.slang
Normal file
|
@ -0,0 +1,42 @@
|
|||
#version 450
|
||||
|
||||
// See dual_filter.slang for copyright and other information.
|
||||
|
||||
#include "parameters.slang"
|
||||
#include "parameters_bloom.slang"
|
||||
|
||||
layout(push_constant) uniform Push {
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
float ADAPT_SPEED;
|
||||
}
|
||||
param;
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO {
|
||||
mat4 MVP;
|
||||
}
|
||||
global;
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
layout(set = 0, binding = 3) uniform sampler2D MovingAverageFeedback;
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(mix(texture(MovingAverageFeedback, vTexCoord).rgb,
|
||||
textureLod(Source, vTexCoord, 9000.1).rgb, param.ADAPT_SPEED),
|
||||
1.0);
|
||||
}
|
35
blurs/shaders/dual_filter/naive_resample.slang
Normal file
35
blurs/shaders/dual_filter/naive_resample.slang
Normal file
|
@ -0,0 +1,35 @@
|
|||
#version 450
|
||||
|
||||
// This is simply stock.slang with a custom input sampler.
|
||||
|
||||
layout(push_constant) uniform Push {
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
}
|
||||
params;
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO {
|
||||
mat4 MVP;
|
||||
}
|
||||
global;
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Input;
|
||||
|
||||
void main() {
|
||||
FragColor = vec4(texture(Input, vTexCoord).rgb, 1.0);
|
||||
}
|
6
blurs/shaders/dual_filter/parameters.slang
Normal file
6
blurs/shaders/dual_filter/parameters.slang
Normal file
|
@ -0,0 +1,6 @@
|
|||
// See dual_filter.slang for copyright and other information.
|
||||
|
||||
// clang-format off
|
||||
#pragma parameter DUAL_FILTER_SETTINGS "=== Dual Filter Blur & Bloom v1.1 settings ===" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter BLUR_RADIUS "Blur radius" 1.0 0.1 7.5 0.1
|
||||
// clang-format on
|
8
blurs/shaders/dual_filter/parameters_bloom.slang
Normal file
8
blurs/shaders/dual_filter/parameters_bloom.slang
Normal file
|
@ -0,0 +1,8 @@
|
|||
// clang-format off
|
||||
#pragma parameter MIN_EXP_INTENSITY "Bloom intensity" 0.6 0.0 2.0 0.05
|
||||
#pragma parameter BLOOM_THRESHOLD "Bloom threshold" 3.5 1.0 10.0 0.1
|
||||
#pragma parameter ADAPT_SPEED "Eye adaptation speed" 0.1 0.0 1.0 0.01
|
||||
#pragma parameter EYE_ADAPTION "Eye adaptation strength: Reduce bloom on bright screens" 0.8 0.0 1.0 0.05
|
||||
#pragma parameter MIN_EXP "Minimum exposure value (where bloom is strongest)" 0.1 0.0 0.95 0.01
|
||||
#pragma parameter MAX_EXP "Maximum exposure value (where bloom is weakest)" 0.55 0.05 1.0 0.01
|
||||
// clang-format on
|
46
blurs/shaders/dual_filter/tonemapping.slang
Normal file
46
blurs/shaders/dual_filter/tonemapping.slang
Normal file
|
@ -0,0 +1,46 @@
|
|||
// See dual_filter.slang for copyright and other information.
|
||||
|
||||
// Tonemapping following
|
||||
// http://filmicworlds.com/blog/filmic-tonemapping-with-piecewise-power-curves/
|
||||
// Parameters:
|
||||
// toeStrength = 0.5
|
||||
// toeLength = 0.5
|
||||
// shoulderStrength = 2.0
|
||||
// shoulderLength = 0.5
|
||||
// shoulderAngle = 1.0
|
||||
float tonemap(float x) {
|
||||
x = clamp(x, 0.0, 16.0);
|
||||
x *= 0.246645;
|
||||
if (x < 0.026840) {
|
||||
// Toe
|
||||
const float y0 = exp(4.324533 + 2.0 * log(x + 1.e-8));
|
||||
return y0 * 0.529110;
|
||||
} else if (x < 0.143452) {
|
||||
// Linear
|
||||
const float x0 = x - 0.013420;
|
||||
const float y0 = 4.054409 * x0;
|
||||
return y0 * 0.529110;
|
||||
} else {
|
||||
// Shoulder
|
||||
const float x0 = 5.0 - x;
|
||||
const float y0 = exp(-20.740919 + 13.369429 * log(x0 + 1.e-8));
|
||||
return y0 * -0.529110 + 1.058221;
|
||||
}
|
||||
}
|
||||
vec3 tonemap(vec3 x) {
|
||||
return vec3(tonemap(x.r), tonemap(x.g), tonemap(x.b));
|
||||
}
|
||||
|
||||
float ambient_to_intensity(vec3 ambient, float min_exp_intensity, float max_exp_intensity,
|
||||
float min_exp, float max_exp) {
|
||||
// Moving average luminance sampled from respective pass.
|
||||
float exposure = dot(vec3(0.30, 0.59, 0.11), ambient);
|
||||
// Lift up exposure value for better control.
|
||||
exposure = sqrt(exposure);
|
||||
// Map from exposure value to bloom intensity, and then to final value
|
||||
return mix(min_exp_intensity, max_exp_intensity, smoothstep(min_exp, max_exp, exposure));
|
||||
}
|
||||
|
||||
vec3 blend_screen(vec3 a, vec3 b) {
|
||||
return 1.0 - (1.0 - a) * (1.0 - b);
|
||||
}
|
40
blurs/shaders/dual_filter/upsample.slang
Normal file
40
blurs/shaders/dual_filter/upsample.slang
Normal file
|
@ -0,0 +1,40 @@
|
|||
#version 450
|
||||
|
||||
// See dual_filter.slang for copyright and other information.
|
||||
|
||||
#include "dual_filter.slang"
|
||||
#include "parameters.slang"
|
||||
|
||||
layout(push_constant) uniform Push {
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
float BLUR_RADIUS;
|
||||
}
|
||||
param;
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO {
|
||||
mat4 MVP;
|
||||
}
|
||||
global;
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
void main() {
|
||||
const vec2 offset = 0.5 * param.SourceSize.zw * param.BLUR_RADIUS;
|
||||
FragColor = vec4(upsample(Source, vTexCoord, offset), 1.0);
|
||||
}
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
Dual filter v1.0, ported to Slang by fishku
|
||||
Copyright (C) 2023
|
||||
Public domain license (CC0)
|
||||
|
||||
Follows the notes of the SIGGRAPH 2015 talk here:
|
||||
https://community.arm.com/cfs-file/__key/communityserver-blogs-components-weblogfiles/00-00-00-20-66/siggraph2015_2D00_mmg_2D00_marius_2D00_notes.pdf
|
||||
Dual filtering is a fast large-radius blur that approximates a Gaussian blur. It is closely
|
||||
related to the popular blur filter by Kawase, but runs faster at equal quality.
|
||||
|
||||
How it works: Any number of downsampling passes are chained with the same number of upsampling
|
||||
passes in an hourglass configuration. Both types of resampling passes exploit bilinear
|
||||
interpolation with carefully chosen coordinates and weights to produce a smooth output.
|
||||
There are just 5 + 8 = 13 texture samples per combined down- and upsampling pass.
|
||||
The effective blur radius increases with the number of passes.
|
||||
|
||||
This implementation adds a configurable blur strength which can diminish or accentuate the
|
||||
effect compared to the reference implementation, equivalent to strength 1.0.
|
||||
A blur strength above 3.0 may lead to artifacts, especially on presets with fewer passes.
|
||||
|
||||
Changelog:
|
||||
v1.0: Initial release.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
#pragma parameter DUAL_FILTER_SETTINGS "=== Dual filter v1.0 settings ===" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter BLUR_STRENGTH "Blur strength" 1.0 0.6 7.5 0.1
|
||||
// clang-format on
|
|
@ -1,47 +0,0 @@
|
|||
#version 450
|
||||
|
||||
// See dual_filter_parameters.slang for copyright and other information.
|
||||
|
||||
#include "dual_filter_parameters.slang"
|
||||
|
||||
layout(push_constant) uniform Push {
|
||||
vec4 SourceSize;
|
||||
vec4 OriginalSize;
|
||||
vec4 OutputSize;
|
||||
uint FrameCount;
|
||||
float BLUR_STRENGTH;
|
||||
}
|
||||
param;
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO {
|
||||
mat4 MVP;
|
||||
}
|
||||
global;
|
||||
|
||||
#pragma stage vertex
|
||||
layout(location = 0) in vec4 Position;
|
||||
layout(location = 1) in vec2 TexCoord;
|
||||
layout(location = 0) out vec2 vTexCoord;
|
||||
|
||||
void main() {
|
||||
gl_Position = global.MVP * Position;
|
||||
vTexCoord = TexCoord;
|
||||
}
|
||||
|
||||
#pragma stage fragment
|
||||
layout(location = 0) in vec2 vTexCoord;
|
||||
layout(location = 0) out vec4 FragColor;
|
||||
layout(set = 0, binding = 2) uniform sampler2D Source;
|
||||
|
||||
void main() {
|
||||
const vec2 halfpixel = 0.5 * param.SourceSize.zw * param.BLUR_STRENGTH;
|
||||
vec3 sum = texture(Source, vTexCoord + vec2(-halfpixel.x * 2.0, 0.0)).rgb;
|
||||
sum += texture(Source, vTexCoord + vec2(-halfpixel.x, halfpixel.y)).rgb * 2.0;
|
||||
sum += texture(Source, vTexCoord + vec2(0.0, halfpixel.y * 2.0)).rgb;
|
||||
sum += texture(Source, vTexCoord + vec2(halfpixel.x, halfpixel.y)).rgb * 2.0;
|
||||
sum += texture(Source, vTexCoord + vec2(halfpixel.x * 2.0, 0.0)).rgb;
|
||||
sum += texture(Source, vTexCoord + vec2(halfpixel.x, -halfpixel.y)).rgb * 2.0;
|
||||
sum += texture(Source, vTexCoord + vec2(0.0, -halfpixel.y * 2.0)).rgb;
|
||||
sum += texture(Source, vTexCoord + vec2(-halfpixel.x, -halfpixel.y)).rgb * 2.0;
|
||||
FragColor = vec4(sum / 12.0, 1.0);
|
||||
}
|
292
crt/crt-1tap-bloom.slangp
Normal file
292
crt/crt-1tap-bloom.slangp
Normal file
|
@ -0,0 +1,292 @@
|
|||
shaders = "26"
|
||||
feedback_pass = "0"
|
||||
shader0 = "shaders/crt-1tap.slang"
|
||||
filter_linear0 = "true"
|
||||
wrap_mode0 = "clamp_to_border"
|
||||
mipmap_input0 = "false"
|
||||
alias0 = ""
|
||||
float_framebuffer0 = "true"
|
||||
srgb_framebuffer0 = "false"
|
||||
scale_type_x0 = "viewport"
|
||||
scale_x0 = "1.000000"
|
||||
scale_type_y0 = "viewport"
|
||||
scale_y0 = "1.000000"
|
||||
shader1 = "../blurs/shaders/kawase/linearize.slang"
|
||||
wrap_mode1 = "clamp_to_border"
|
||||
mipmap_input1 = "false"
|
||||
alias1 = "Input"
|
||||
float_framebuffer1 = "true"
|
||||
srgb_framebuffer1 = "false"
|
||||
scale_type_x1 = "source"
|
||||
scale_x1 = "1.000000"
|
||||
scale_type_y1 = "source"
|
||||
scale_y1 = "1.000000"
|
||||
shader2 = "../blurs/shaders/dual_filter/downsample_bloom.slang"
|
||||
filter_linear2 = "true"
|
||||
wrap_mode2 = "mirrored_repeat"
|
||||
mipmap_input2 = "false"
|
||||
alias2 = ""
|
||||
float_framebuffer2 = "true"
|
||||
srgb_framebuffer2 = "false"
|
||||
scale_type_x2 = "viewport"
|
||||
scale_x2 = "0.700000"
|
||||
scale_type_y2 = "viewport"
|
||||
scale_y2 = "0.700000"
|
||||
shader3 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear3 = "true"
|
||||
wrap_mode3 = "mirrored_repeat"
|
||||
mipmap_input3 = "false"
|
||||
alias3 = ""
|
||||
float_framebuffer3 = "true"
|
||||
srgb_framebuffer3 = "false"
|
||||
scale_type_x3 = "source"
|
||||
scale_x3 = "1.000000"
|
||||
scale_type_y3 = "source"
|
||||
scale_y3 = "1.000000"
|
||||
shader4 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear4 = "true"
|
||||
wrap_mode4 = "mirrored_repeat"
|
||||
mipmap_input4 = "false"
|
||||
alias4 = ""
|
||||
float_framebuffer4 = "true"
|
||||
srgb_framebuffer4 = "false"
|
||||
scale_type_x4 = "source"
|
||||
scale_x4 = "0.500000"
|
||||
scale_type_y4 = "source"
|
||||
scale_y4 = "0.500000"
|
||||
shader5 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear5 = "true"
|
||||
wrap_mode5 = "mirrored_repeat"
|
||||
mipmap_input5 = "false"
|
||||
alias5 = "Scale1"
|
||||
float_framebuffer5 = "true"
|
||||
srgb_framebuffer5 = "false"
|
||||
scale_type_x5 = "source"
|
||||
scale_x5 = "2.000000"
|
||||
scale_type_y5 = "source"
|
||||
scale_y5 = "2.000000"
|
||||
shader6 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear6 = "true"
|
||||
wrap_mode6 = "mirrored_repeat"
|
||||
mipmap_input6 = "false"
|
||||
alias6 = ""
|
||||
float_framebuffer6 = "true"
|
||||
srgb_framebuffer6 = "false"
|
||||
scale_type_x6 = "source"
|
||||
scale_x6 = "0.500000"
|
||||
scale_type_y6 = "source"
|
||||
scale_y6 = "0.500000"
|
||||
shader7 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear7 = "true"
|
||||
wrap_mode7 = "mirrored_repeat"
|
||||
mipmap_input7 = "false"
|
||||
alias7 = ""
|
||||
float_framebuffer7 = "true"
|
||||
srgb_framebuffer7 = "false"
|
||||
scale_type_x7 = "source"
|
||||
scale_x7 = "0.500000"
|
||||
scale_type_y7 = "source"
|
||||
scale_y7 = "0.500000"
|
||||
shader8 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear8 = "true"
|
||||
wrap_mode8 = "mirrored_repeat"
|
||||
mipmap_input8 = "false"
|
||||
alias8 = "Scale2"
|
||||
float_framebuffer8 = "true"
|
||||
srgb_framebuffer8 = "false"
|
||||
scale_type_x8 = "source"
|
||||
scale_x8 = "2.000000"
|
||||
scale_type_y8 = "source"
|
||||
scale_y8 = "2.000000"
|
||||
shader9 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear9 = "true"
|
||||
wrap_mode9 = "mirrored_repeat"
|
||||
mipmap_input9 = "false"
|
||||
alias9 = ""
|
||||
float_framebuffer9 = "true"
|
||||
srgb_framebuffer9 = "false"
|
||||
scale_type_x9 = "source"
|
||||
scale_x9 = "0.500000"
|
||||
scale_type_y9 = "source"
|
||||
scale_y9 = "0.500000"
|
||||
shader10 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear10 = "true"
|
||||
wrap_mode10 = "mirrored_repeat"
|
||||
mipmap_input10 = "false"
|
||||
alias10 = ""
|
||||
float_framebuffer10 = "true"
|
||||
srgb_framebuffer10 = "false"
|
||||
scale_type_x10 = "source"
|
||||
scale_x10 = "0.500000"
|
||||
scale_type_y10 = "source"
|
||||
scale_y10 = "0.500000"
|
||||
shader11 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear11 = "true"
|
||||
wrap_mode11 = "mirrored_repeat"
|
||||
mipmap_input11 = "false"
|
||||
alias11 = "Scale3"
|
||||
float_framebuffer11 = "true"
|
||||
srgb_framebuffer11 = "false"
|
||||
scale_type_x11 = "source"
|
||||
scale_x11 = "2.000000"
|
||||
scale_type_y11 = "source"
|
||||
scale_y11 = "2.000000"
|
||||
shader12 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear12 = "true"
|
||||
wrap_mode12 = "mirrored_repeat"
|
||||
mipmap_input12 = "false"
|
||||
alias12 = ""
|
||||
float_framebuffer12 = "true"
|
||||
srgb_framebuffer12 = "false"
|
||||
scale_type_x12 = "source"
|
||||
scale_x12 = "0.500000"
|
||||
scale_type_y12 = "source"
|
||||
scale_y12 = "0.500000"
|
||||
shader13 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear13 = "true"
|
||||
wrap_mode13 = "mirrored_repeat"
|
||||
mipmap_input13 = "false"
|
||||
alias13 = ""
|
||||
float_framebuffer13 = "true"
|
||||
srgb_framebuffer13 = "false"
|
||||
scale_type_x13 = "source"
|
||||
scale_x13 = "0.500000"
|
||||
scale_type_y13 = "source"
|
||||
scale_y13 = "0.500000"
|
||||
shader14 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear14 = "true"
|
||||
wrap_mode14 = "mirrored_repeat"
|
||||
mipmap_input14 = "false"
|
||||
alias14 = "Scale4"
|
||||
float_framebuffer14 = "true"
|
||||
srgb_framebuffer14 = "false"
|
||||
scale_type_x14 = "source"
|
||||
scale_x14 = "2.000000"
|
||||
scale_type_y14 = "source"
|
||||
scale_y14 = "2.000000"
|
||||
shader15 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear15 = "true"
|
||||
wrap_mode15 = "mirrored_repeat"
|
||||
mipmap_input15 = "false"
|
||||
alias15 = ""
|
||||
float_framebuffer15 = "true"
|
||||
srgb_framebuffer15 = "false"
|
||||
scale_type_x15 = "source"
|
||||
scale_x15 = "0.500000"
|
||||
scale_type_y15 = "source"
|
||||
scale_y15 = "0.500000"
|
||||
shader16 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear16 = "true"
|
||||
wrap_mode16 = "mirrored_repeat"
|
||||
mipmap_input16 = "false"
|
||||
alias16 = ""
|
||||
float_framebuffer16 = "true"
|
||||
srgb_framebuffer16 = "false"
|
||||
scale_type_x16 = "source"
|
||||
scale_x16 = "0.500000"
|
||||
scale_type_y16 = "source"
|
||||
scale_y16 = "0.500000"
|
||||
shader17 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear17 = "true"
|
||||
wrap_mode17 = "mirrored_repeat"
|
||||
mipmap_input17 = "false"
|
||||
alias17 = "Scale5"
|
||||
float_framebuffer17 = "true"
|
||||
srgb_framebuffer17 = "false"
|
||||
scale_type_x17 = "source"
|
||||
scale_x17 = "2.000000"
|
||||
scale_type_y17 = "source"
|
||||
scale_y17 = "2.000000"
|
||||
shader18 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear18 = "true"
|
||||
wrap_mode18 = "mirrored_repeat"
|
||||
mipmap_input18 = "false"
|
||||
alias18 = ""
|
||||
float_framebuffer18 = "true"
|
||||
srgb_framebuffer18 = "false"
|
||||
scale_type_x18 = "source"
|
||||
scale_x18 = "0.500000"
|
||||
scale_type_y18 = "source"
|
||||
scale_y18 = "0.500000"
|
||||
shader19 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear19 = "true"
|
||||
wrap_mode19 = "mirrored_repeat"
|
||||
mipmap_input19 = "false"
|
||||
alias19 = ""
|
||||
float_framebuffer19 = "true"
|
||||
srgb_framebuffer19 = "false"
|
||||
scale_type_x19 = "source"
|
||||
scale_x19 = "0.500000"
|
||||
scale_type_y19 = "source"
|
||||
scale_y19 = "0.500000"
|
||||
shader20 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear20 = "true"
|
||||
wrap_mode20 = "mirrored_repeat"
|
||||
mipmap_input20 = "false"
|
||||
alias20 = "Scale6"
|
||||
float_framebuffer20 = "true"
|
||||
srgb_framebuffer20 = "false"
|
||||
scale_type_x20 = "source"
|
||||
scale_x20 = "2.000000"
|
||||
scale_type_y20 = "source"
|
||||
scale_y20 = "2.000000"
|
||||
shader21 = "../blurs/shaders/dual_filter/naive_resample.slang"
|
||||
filter_linear21 = "true"
|
||||
wrap_mode21 = "mirrored_repeat"
|
||||
mipmap_input21 = "false"
|
||||
alias21 = ""
|
||||
float_framebuffer21 = "true"
|
||||
srgb_framebuffer21 = "false"
|
||||
scale_type_x21 = "absolute"
|
||||
scale_x21 = "128"
|
||||
scale_type_y21 = "absolute"
|
||||
scale_y21 = "128"
|
||||
shader22 = "../blurs/shaders/dual_filter/moving_avg.slang"
|
||||
filter_linear22 = "true"
|
||||
wrap_mode22 = "clamp_to_border"
|
||||
mipmap_input22 = "true"
|
||||
alias22 = "MovingAverage"
|
||||
float_framebuffer22 = "true"
|
||||
srgb_framebuffer22 = "false"
|
||||
scale_type_x22 = "absolute"
|
||||
scale_x22 = "2"
|
||||
scale_type_y22 = "absolute"
|
||||
scale_y22 = "2"
|
||||
shader23 = "../blurs/shaders/dual_filter/bloom_blend.slang"
|
||||
filter_linear23 = "true"
|
||||
wrap_mode23 = "clamp_to_border"
|
||||
mipmap_input23 = "false"
|
||||
alias23 = ""
|
||||
float_framebuffer23 = "true"
|
||||
srgb_framebuffer23 = "false"
|
||||
scale_type_x23 = "viewport"
|
||||
scale_x23 = "1.000000"
|
||||
scale_type_y23 = "viewport"
|
||||
scale_y23 = "1.000000"
|
||||
shader24 = "../blurs/shaders/kawase/delinearize.slang"
|
||||
filter_linear24 = "true"
|
||||
wrap_mode24 = "clamp_to_border"
|
||||
mipmap_input24 = "false"
|
||||
alias24 = ""
|
||||
float_framebuffer24 = "true"
|
||||
srgb_framebuffer24 = "false"
|
||||
scale_type_x24 = "viewport"
|
||||
scale_x24 = "1.000000"
|
||||
scale_type_y24 = "viewport"
|
||||
scale_y24 = "1.000000"
|
||||
shader25 = "../sharpen/shaders/rcas.slang"
|
||||
filter_linear25 = "false"
|
||||
wrap_mode25 = "clamp_to_border"
|
||||
mipmap_input25 = "false"
|
||||
alias25 = ""
|
||||
float_framebuffer25 = "false"
|
||||
srgb_framebuffer25 = "false"
|
||||
scale_type_x25 = "source"
|
||||
scale_x25 = "1.000000"
|
||||
scale_type_y25 = "source"
|
||||
scale_y25 = "1.000000"
|
||||
BLUR_RADIUS = "2.000000"
|
||||
MIN_EXP_INTENSITY = "0.500000"
|
||||
BLOOM_THRESHOLD = "2.500000"
|
||||
EYE_ADAPTION = "0.850000"
|
||||
RCAS_STRENGTH = "1.000000"
|
224
crt/crt-1tap-bloom_fast.slangp
Normal file
224
crt/crt-1tap-bloom_fast.slangp
Normal file
|
@ -0,0 +1,224 @@
|
|||
shaders = "20"
|
||||
feedback_pass = "0"
|
||||
shader0 = "shaders/crt-1tap.slang"
|
||||
filter_linear0 = "true"
|
||||
wrap_mode0 = "clamp_to_border"
|
||||
mipmap_input0 = "false"
|
||||
alias0 = ""
|
||||
float_framebuffer0 = "true"
|
||||
srgb_framebuffer0 = "false"
|
||||
scale_type_x0 = "viewport"
|
||||
scale_x0 = "1.000000"
|
||||
scale_type_y0 = "viewport"
|
||||
scale_y0 = "1.000000"
|
||||
shader1 = "../blurs/shaders/kawase/linearize.slang"
|
||||
wrap_mode1 = "clamp_to_border"
|
||||
mipmap_input1 = "false"
|
||||
alias1 = "Input"
|
||||
float_framebuffer1 = "true"
|
||||
srgb_framebuffer1 = "false"
|
||||
scale_type_x1 = "source"
|
||||
scale_x1 = "1.000000"
|
||||
scale_type_y1 = "source"
|
||||
scale_y1 = "1.000000"
|
||||
shader2 = "../blurs/shaders/dual_filter/downsample_bloom.slang"
|
||||
filter_linear2 = "true"
|
||||
wrap_mode2 = "mirrored_repeat"
|
||||
mipmap_input2 = "false"
|
||||
alias2 = ""
|
||||
float_framebuffer2 = "true"
|
||||
srgb_framebuffer2 = "false"
|
||||
scale_type_x2 = "viewport"
|
||||
scale_x2 = "0.400000"
|
||||
scale_type_y2 = "viewport"
|
||||
scale_y2 = "0.400000"
|
||||
shader3 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear3 = "true"
|
||||
wrap_mode3 = "mirrored_repeat"
|
||||
mipmap_input3 = "false"
|
||||
alias3 = ""
|
||||
float_framebuffer3 = "true"
|
||||
srgb_framebuffer3 = "false"
|
||||
scale_type_x3 = "source"
|
||||
scale_x3 = "1.000000"
|
||||
scale_type_y3 = "source"
|
||||
scale_y3 = "1.000000"
|
||||
shader4 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear4 = "true"
|
||||
wrap_mode4 = "mirrored_repeat"
|
||||
mipmap_input4 = "false"
|
||||
alias4 = ""
|
||||
float_framebuffer4 = "true"
|
||||
srgb_framebuffer4 = "false"
|
||||
scale_type_x4 = "source"
|
||||
scale_x4 = "0.500000"
|
||||
scale_type_y4 = "source"
|
||||
scale_y4 = "0.500000"
|
||||
shader5 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear5 = "true"
|
||||
wrap_mode5 = "mirrored_repeat"
|
||||
mipmap_input5 = "false"
|
||||
alias5 = "Scale1"
|
||||
float_framebuffer5 = "true"
|
||||
srgb_framebuffer5 = "false"
|
||||
scale_type_x5 = "source"
|
||||
scale_x5 = "2.000000"
|
||||
scale_type_y5 = "source"
|
||||
scale_y5 = "2.000000"
|
||||
shader6 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear6 = "true"
|
||||
wrap_mode6 = "mirrored_repeat"
|
||||
mipmap_input6 = "false"
|
||||
alias6 = ""
|
||||
float_framebuffer6 = "true"
|
||||
srgb_framebuffer6 = "false"
|
||||
scale_type_x6 = "source"
|
||||
scale_x6 = "0.500000"
|
||||
scale_type_y6 = "source"
|
||||
scale_y6 = "0.500000"
|
||||
shader7 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear7 = "true"
|
||||
wrap_mode7 = "mirrored_repeat"
|
||||
mipmap_input7 = "false"
|
||||
alias7 = ""
|
||||
float_framebuffer7 = "true"
|
||||
srgb_framebuffer7 = "false"
|
||||
scale_type_x7 = "source"
|
||||
scale_x7 = "0.500000"
|
||||
scale_type_y7 = "source"
|
||||
scale_y7 = "0.500000"
|
||||
shader8 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear8 = "true"
|
||||
wrap_mode8 = "mirrored_repeat"
|
||||
mipmap_input8 = "false"
|
||||
alias8 = "Scale2"
|
||||
float_framebuffer8 = "true"
|
||||
srgb_framebuffer8 = "false"
|
||||
scale_type_x8 = "source"
|
||||
scale_x8 = "2.000000"
|
||||
scale_type_y8 = "source"
|
||||
scale_y8 = "2.000000"
|
||||
shader9 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear9 = "true"
|
||||
wrap_mode9 = "mirrored_repeat"
|
||||
mipmap_input9 = "false"
|
||||
alias9 = ""
|
||||
float_framebuffer9 = "true"
|
||||
srgb_framebuffer9 = "false"
|
||||
scale_type_x9 = "source"
|
||||
scale_x9 = "0.500000"
|
||||
scale_type_y9 = "source"
|
||||
scale_y9 = "0.500000"
|
||||
shader10 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear10 = "true"
|
||||
wrap_mode10 = "mirrored_repeat"
|
||||
mipmap_input10 = "false"
|
||||
alias10 = ""
|
||||
float_framebuffer10 = "true"
|
||||
srgb_framebuffer10 = "false"
|
||||
scale_type_x10 = "source"
|
||||
scale_x10 = "0.500000"
|
||||
scale_type_y10 = "source"
|
||||
scale_y10 = "0.500000"
|
||||
shader11 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear11 = "true"
|
||||
wrap_mode11 = "mirrored_repeat"
|
||||
mipmap_input11 = "false"
|
||||
alias11 = "Scale3"
|
||||
float_framebuffer11 = "true"
|
||||
srgb_framebuffer11 = "false"
|
||||
scale_type_x11 = "source"
|
||||
scale_x11 = "2.000000"
|
||||
scale_type_y11 = "source"
|
||||
scale_y11 = "2.000000"
|
||||
shader12 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear12 = "true"
|
||||
wrap_mode12 = "mirrored_repeat"
|
||||
mipmap_input12 = "false"
|
||||
alias12 = ""
|
||||
float_framebuffer12 = "true"
|
||||
srgb_framebuffer12 = "false"
|
||||
scale_type_x12 = "source"
|
||||
scale_x12 = "0.500000"
|
||||
scale_type_y12 = "source"
|
||||
scale_y12 = "0.500000"
|
||||
shader13 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear13 = "true"
|
||||
wrap_mode13 = "mirrored_repeat"
|
||||
mipmap_input13 = "false"
|
||||
alias13 = ""
|
||||
float_framebuffer13 = "true"
|
||||
srgb_framebuffer13 = "false"
|
||||
scale_type_x13 = "source"
|
||||
scale_x13 = "0.500000"
|
||||
scale_type_y13 = "source"
|
||||
scale_y13 = "0.500000"
|
||||
shader14 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear14 = "true"
|
||||
wrap_mode14 = "mirrored_repeat"
|
||||
mipmap_input14 = "false"
|
||||
alias14 = "Scale4"
|
||||
float_framebuffer14 = "true"
|
||||
srgb_framebuffer14 = "false"
|
||||
scale_type_x14 = "source"
|
||||
scale_x14 = "2.000000"
|
||||
scale_type_y14 = "source"
|
||||
scale_y14 = "2.000000"
|
||||
shader15 = "../blurs/shaders/dual_filter/naive_resample.slang"
|
||||
filter_linear15 = "true"
|
||||
wrap_mode15 = "mirrored_repeat"
|
||||
mipmap_input15 = "false"
|
||||
alias15 = ""
|
||||
float_framebuffer15 = "true"
|
||||
srgb_framebuffer15 = "false"
|
||||
scale_type_x15 = "absolute"
|
||||
scale_x15 = "64"
|
||||
scale_type_y15 = "absolute"
|
||||
scale_y15 = "64"
|
||||
shader16 = "../blurs/shaders/dual_filter/moving_avg.slang"
|
||||
filter_linear16 = "true"
|
||||
wrap_mode16 = "clamp_to_border"
|
||||
mipmap_input16 = "true"
|
||||
alias16 = "MovingAverage"
|
||||
float_framebuffer16 = "true"
|
||||
srgb_framebuffer16 = "false"
|
||||
scale_type_x16 = "absolute"
|
||||
scale_x16 = "2"
|
||||
scale_type_y16 = "absolute"
|
||||
scale_y16 = "2"
|
||||
shader17 = "../blurs/shaders/dual_filter/bloom_blend_fast.slang"
|
||||
filter_linear17 = "true"
|
||||
wrap_mode17 = "clamp_to_border"
|
||||
mipmap_input17 = "false"
|
||||
alias17 = ""
|
||||
float_framebuffer17 = "true"
|
||||
srgb_framebuffer17 = "false"
|
||||
scale_type_x17 = "viewport"
|
||||
scale_x17 = "1.000000"
|
||||
scale_type_y17 = "viewport"
|
||||
scale_y17 = "1.000000"
|
||||
shader18 = "../blurs/shaders/kawase/delinearize.slang"
|
||||
filter_linear18 = "true"
|
||||
wrap_mode18 = "clamp_to_border"
|
||||
mipmap_input18 = "false"
|
||||
alias18 = ""
|
||||
float_framebuffer18 = "true"
|
||||
srgb_framebuffer18 = "false"
|
||||
scale_type_x18 = "viewport"
|
||||
scale_x18 = "1.000000"
|
||||
scale_type_y18 = "viewport"
|
||||
scale_y18 = "1.000000"
|
||||
shader19 = "../sharpen/shaders/rcas.slang"
|
||||
filter_linear19 = "false"
|
||||
wrap_mode19 = "clamp_to_border"
|
||||
mipmap_input19 = "false"
|
||||
alias19 = ""
|
||||
float_framebuffer19 = "false"
|
||||
srgb_framebuffer19 = "false"
|
||||
scale_type_x19 = "source"
|
||||
scale_x19 = "1.000000"
|
||||
scale_type_y19 = "source"
|
||||
scale_y19 = "1.000000"
|
||||
MIN_EXP_INTENSITY = "0.650000"
|
||||
BLOOM_THRESHOLD = "2.500001"
|
||||
RCAS_STRENGTH = "1.000000"
|
115
crt/crt-1tap-bloom_fastest.slangp
Normal file
115
crt/crt-1tap-bloom_fastest.slangp
Normal file
|
@ -0,0 +1,115 @@
|
|||
shaders = "10"
|
||||
feedback_pass = "0"
|
||||
shader0 = "shaders/crt-1tap.slang"
|
||||
filter_linear0 = "true"
|
||||
wrap_mode0 = "clamp_to_border"
|
||||
mipmap_input0 = "false"
|
||||
alias0 = ""
|
||||
float_framebuffer0 = "true"
|
||||
srgb_framebuffer0 = "false"
|
||||
scale_type_x0 = "viewport"
|
||||
scale_x0 = "1.000000"
|
||||
scale_type_y0 = "viewport"
|
||||
scale_y0 = "1.000000"
|
||||
shader1 = "../blurs/shaders/kawase/linearize.slang"
|
||||
wrap_mode1 = "clamp_to_border"
|
||||
mipmap_input1 = "false"
|
||||
alias1 = "Input"
|
||||
float_framebuffer1 = "true"
|
||||
srgb_framebuffer1 = "false"
|
||||
scale_type_x1 = "source"
|
||||
scale_x1 = "1.000000"
|
||||
scale_type_y1 = "source"
|
||||
scale_y1 = "1.000000"
|
||||
shader2 = "../blurs/shaders/dual_filter/downsample_bloom.slang"
|
||||
filter_linear2 = "false"
|
||||
wrap_mode2 = "mirrored_repeat"
|
||||
mipmap_input2 = "false"
|
||||
alias2 = "Downsample1"
|
||||
float_framebuffer2 = "true"
|
||||
srgb_framebuffer2 = "false"
|
||||
scale_type_x2 = "source"
|
||||
scale_x2 = "0.500000"
|
||||
scale_type_y2 = "source"
|
||||
scale_y2 = "0.500000"
|
||||
shader3 = "../blurs/shaders/dual_filter/downsample.slang"
|
||||
filter_linear3 = "true"
|
||||
wrap_mode3 = "mirrored_repeat"
|
||||
mipmap_input3 = "false"
|
||||
alias3 = "Downsample2"
|
||||
float_framebuffer3 = "true"
|
||||
srgb_framebuffer3 = "false"
|
||||
scale_type_x3 = "source"
|
||||
scale_x3 = "0.500000"
|
||||
scale_type_y3 = "source"
|
||||
scale_y3 = "0.500000"
|
||||
shader4 = "../blurs/shaders/dual_filter/upsample.slang"
|
||||
filter_linear4 = "true"
|
||||
wrap_mode4 = "mirrored_repeat"
|
||||
mipmap_input4 = "false"
|
||||
alias4 = "Upsample"
|
||||
float_framebuffer4 = "true"
|
||||
srgb_framebuffer4 = "false"
|
||||
scale_type_x4 = "source"
|
||||
scale_x4 = "2.000000"
|
||||
scale_type_y4 = "source"
|
||||
scale_y4 = "2.000000"
|
||||
shader5 = "../blurs/shaders/dual_filter/naive_resample.slang"
|
||||
filter_linear5 = "true"
|
||||
wrap_mode5 = "clamp_to_border"
|
||||
mipmap_input5 = "false"
|
||||
alias5 = ""
|
||||
float_framebuffer5 = "true"
|
||||
srgb_framebuffer5 = "false"
|
||||
scale_type_x5 = "absolute"
|
||||
scale_x5 = "64"
|
||||
scale_type_y5 = "absolute"
|
||||
scale_y5 = "64"
|
||||
shader6 = "../blurs/shaders/dual_filter/moving_avg.slang"
|
||||
filter_linear6 = "true"
|
||||
wrap_mode6 = "mirrored_repeat"
|
||||
mipmap_input6 = "true"
|
||||
alias6 = "MovingAverage"
|
||||
float_framebuffer6 = "true"
|
||||
srgb_framebuffer6 = "false"
|
||||
scale_type_x6 = "absolute"
|
||||
scale_x6 = "2"
|
||||
scale_type_y6 = "absolute"
|
||||
scale_y6 = "2"
|
||||
shader7 = "../blurs/shaders/dual_filter/bloom_blend_fastest.slang"
|
||||
filter_linear7 = "true"
|
||||
wrap_mode7 = "mirrored_repeat"
|
||||
mipmap_input7 = "false"
|
||||
alias7 = ""
|
||||
float_framebuffer7 = "true"
|
||||
srgb_framebuffer7 = "false"
|
||||
scale_type_x7 = "viewport"
|
||||
scale_x7 = "1.000000"
|
||||
scale_type_y7 = "viewport"
|
||||
scale_y7 = "1.000000"
|
||||
shader8 = "../blurs/shaders/kawase/delinearize.slang"
|
||||
filter_linear8 = "false"
|
||||
wrap_mode8 = "clamp_to_border"
|
||||
mipmap_input8 = "false"
|
||||
alias8 = ""
|
||||
float_framebuffer8 = "true"
|
||||
srgb_framebuffer8 = "false"
|
||||
scale_type_x8 = "viewport"
|
||||
scale_x8 = "1.000000"
|
||||
scale_type_y8 = "viewport"
|
||||
scale_y8 = "1.000000"
|
||||
shader9 = "../sharpen/shaders/rcas.slang"
|
||||
filter_linear9 = "false"
|
||||
wrap_mode9 = "clamp_to_border"
|
||||
mipmap_input9 = "false"
|
||||
alias9 = ""
|
||||
float_framebuffer9 = "false"
|
||||
srgb_framebuffer9 = "false"
|
||||
scale_type_x9 = "source"
|
||||
scale_x9 = "1.000000"
|
||||
scale_type_y9 = "source"
|
||||
scale_y9 = "1.000000"
|
||||
BLUR_RADIUS = "2.000000"
|
||||
MIN_EXP_INTENSITY = "0.450000"
|
||||
BLOOM_THRESHOLD = "3.000000"
|
||||
RCAS_STRENGTH = "1.000000"
|
|
@ -1,7 +1,7 @@
|
|||
#version 450
|
||||
|
||||
/*
|
||||
crt-1tap v1.1 by fishku
|
||||
crt-1tap v1.2 by fishku
|
||||
Copyright (C) 2023
|
||||
Public domain license (CC0)
|
||||
|
||||
|
@ -21,18 +21,19 @@
|
|||
for even and odd integer scaling.
|
||||
|
||||
Changelog:
|
||||
v1.2: Better scanline sharpness; Minor cleanups.
|
||||
v1.1: Update license; Better defaults; Don't compute alpha.
|
||||
v1.0: Initial release.
|
||||
*/
|
||||
|
||||
// clang-format off
|
||||
#pragma parameter CRT1TAP_SETTINGS "=== CRT-1tap settings ===" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter MIN_THICK "MIN_THICK: Scanline thickness of dark pixels." 0.3 0.0 1.4 0.05
|
||||
#pragma parameter MAX_THICK "MAX_THICK: Scanline thickness of bright pixels." 1.05 0.0 1.4 0.05
|
||||
#pragma parameter V_SHARP "V_SHARP: Vertical sharpness of the scanline" 0.2 0.0 1.0 0.05
|
||||
#pragma parameter H_SHARP "H_SHARP: Horizontal sharpness of pixel transitions." 0.15 0.0 1.0 0.05
|
||||
#pragma parameter SUBPX_POS "SUBPX_POS: Scanline subpixel position." 0.15 -0.5 0.5 0.01
|
||||
#pragma parameter THICK_FALLOFF "THICK_FALLOFF: Reduction of thinner scanlines." 0.65 0.2 2.0 0.05
|
||||
#pragma parameter CRT1TAP_SETTINGS "=== CRT-1tap v1.2 settings ===" 0.0 0.0 1.0 1.0
|
||||
#pragma parameter MIN_THICK "Scanline thickness of dark pixels" 0.3 0.0 1.4 0.05
|
||||
#pragma parameter MAX_THICK "Scanline thickness of bright pixels" 0.9 0.0 1.4 0.05
|
||||
#pragma parameter V_SHARP "Vertical sharpness of the scanline" 0.5 0.0 1.0 0.05
|
||||
#pragma parameter H_SHARP "Horizontal sharpness of pixel transitions" 0.15 0.0 1.0 0.05
|
||||
#pragma parameter SUBPX_POS "Scanline subpixel position" 0.3 -0.5 0.5 0.01
|
||||
#pragma parameter THICK_FALLOFF "Reduction / increase of thinner scanlines" 0.65 0.2 2.0 0.05
|
||||
// clang-format on
|
||||
|
||||
layout(push_constant) uniform Push {
|
||||
|
@ -47,7 +48,9 @@ layout(push_constant) uniform Push {
|
|||
}
|
||||
param;
|
||||
|
||||
layout(std140, set = 0, binding = 0) uniform UBO { mat4 MVP; }
|
||||
layout(std140, set = 0, binding = 0) uniform UBO {
|
||||
mat4 MVP;
|
||||
}
|
||||
global;
|
||||
|
||||
#pragma stage vertex
|
||||
|
@ -68,34 +71,27 @@ layout(set = 0, binding = 2) uniform sampler2D Original;
|
|||
|
||||
void main() {
|
||||
float src_x_int;
|
||||
const float src_x_fract =
|
||||
modf(vTexCoord.x * param.SourceSize.x - 0.5f, src_x_int);
|
||||
const float src_x_fract = modf(vTexCoord.x * param.SourceSize.x - 0.5, src_x_int);
|
||||
|
||||
float src_y_int;
|
||||
const float src_y_fract =
|
||||
modf(vTexCoord.y * param.SourceSize.y - param.SUBPX_POS, src_y_int);
|
||||
modf(vTexCoord.y * param.SourceSize.y - param.SUBPX_POS, src_y_int) - 0.5;
|
||||
|
||||
// Function similar to smoothstep and sigmoid.
|
||||
const float s = sign(src_x_fract - 0.5f);
|
||||
const float o = (1.0f + s) * 0.5f;
|
||||
const float s = sign(src_x_fract - 0.5);
|
||||
const float o = (1.0 + s) * 0.5;
|
||||
const float src_x =
|
||||
src_x_int + o -
|
||||
0.5f * s *
|
||||
pow(2.0f * (o - s * src_x_fract), mix(1.0f, 6.0f, param.H_SHARP));
|
||||
src_x_int + o - 0.5 * s * pow(2.0 * (o - s * src_x_fract), mix(1.0, 6.0, param.H_SHARP));
|
||||
|
||||
const vec3 signal =
|
||||
texture(Source, vec2((src_x + 0.5f) * param.SourceSize.z,
|
||||
(src_y_int + 0.5f) * param.SourceSize.w))
|
||||
.rgb;
|
||||
const vec3 signal = texture(Source, vec2((src_x + 0.5) * param.SourceSize.z,
|
||||
(src_y_int + 0.5) * param.SourceSize.w))
|
||||
.rgb;
|
||||
|
||||
// Vectorize operations for speed.
|
||||
const float eff_v_sharp = 3.0f + 50.0f * param.V_SHARP * param.V_SHARP;
|
||||
const float eff_v_sharp = 3.0 + 50.0 * param.V_SHARP * param.V_SHARP;
|
||||
const vec3 radius =
|
||||
pow(mix(param.MIN_THICK.xxx, param.MAX_THICK.xxx, signal), param.THICK_FALLOFF.xxx) * 0.5;
|
||||
FragColor.rgb =
|
||||
signal *
|
||||
clamp(eff_v_sharp *
|
||||
((pow(mix(param.MIN_THICK.xxx, param.MAX_THICK.xxx, signal),
|
||||
param.THICK_FALLOFF.xxx) *
|
||||
0.5f) -
|
||||
abs(src_y_fract - 0.5f)),
|
||||
0.0f, 1.0f);
|
||||
signal * clamp(0.25 - eff_v_sharp * (src_y_fract * src_y_fract - radius * radius),
|
||||
0.0, 1.0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue