77 lines
2.1 KiB
Text
77 lines
2.1 KiB
Text
|
|
//
|
||
|
|
layout (local_size_x = 16, local_size_y = 16) in;
|
||
|
|
|
||
|
|
layout (set = 0, binding = 0) uniform texture2D kTextures2D[];
|
||
|
|
layout (set = 0, binding = 1) uniform sampler kSamplers[];
|
||
|
|
|
||
|
|
layout (set = 0, binding = 2, rgba8) uniform writeonly image2D kTextures2DOut[];
|
||
|
|
|
||
|
|
ivec2 textureBindlessSize2D(uint textureid) {
|
||
|
|
return textureSize(nonuniformEXT(kTextures2D[textureid]), 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
vec4 textureBindless2D(uint textureid, vec2 uv) {
|
||
|
|
return textureLod(nonuniformEXT(sampler2D(kTextures2D[textureid], kSamplers[0])), uv, 0);
|
||
|
|
}
|
||
|
|
|
||
|
|
layout (constant_id = 0) const bool kIsHorizontal = true;
|
||
|
|
|
||
|
|
layout(push_constant) uniform PushConstants {
|
||
|
|
uint texDepth;
|
||
|
|
uint texIn;
|
||
|
|
uint texOut;
|
||
|
|
float depthThreshold;
|
||
|
|
} pc;
|
||
|
|
|
||
|
|
const int kFilterSize = 17;
|
||
|
|
|
||
|
|
// https://drdesten.github.io/web/tools/gaussian_kernel/
|
||
|
|
const float gaussWeights[kFilterSize] = float[](
|
||
|
|
0.00001525878906,
|
||
|
|
0.0002441406250,
|
||
|
|
0.001831054688,
|
||
|
|
0.008544921875,
|
||
|
|
0.02777099609,
|
||
|
|
0.06665039063,
|
||
|
|
0.1221923828,
|
||
|
|
0.1745605469,
|
||
|
|
0.1963806152,
|
||
|
|
0.1745605469,
|
||
|
|
0.1221923828,
|
||
|
|
0.06665039063,
|
||
|
|
0.02777099609,
|
||
|
|
0.008544921875,
|
||
|
|
0.001831054688,
|
||
|
|
0.0002441406250,
|
||
|
|
0.00001525878906
|
||
|
|
);
|
||
|
|
|
||
|
|
void main() {
|
||
|
|
const vec2 size = textureBindlessSize2D(pc.texIn).xy;
|
||
|
|
const vec2 xy = gl_GlobalInvocationID.xy;
|
||
|
|
|
||
|
|
if (xy.x > size.x || xy.y > size.y)
|
||
|
|
return;
|
||
|
|
|
||
|
|
const vec2 texCoord = (gl_GlobalInvocationID.xy + vec2(0.5)) / size;
|
||
|
|
|
||
|
|
const float texScaler = 1.0 / (kIsHorizontal ? size.x : size.y);
|
||
|
|
|
||
|
|
vec3 c = vec3(0.0);
|
||
|
|
|
||
|
|
vec3 fragColor = textureBindless2D(pc.texIn, texCoord).rgb;
|
||
|
|
float fragDepth = textureBindless2D(pc.texDepth, texCoord).r;
|
||
|
|
|
||
|
|
for ( int i = 0; i != kFilterSize; i++ ) {
|
||
|
|
float offset = float(i - kFilterSize/2);
|
||
|
|
vec2 uv = texCoord + texScaler * (kIsHorizontal ? vec2(offset, 0) : vec2(0, offset));
|
||
|
|
vec3 color = textureBindless2D(pc.texIn, uv).rgb;
|
||
|
|
float depth = textureBindless2D(pc.texDepth, uv).r;
|
||
|
|
// bilateral blur
|
||
|
|
float weight = clamp(abs(depth - fragDepth) * pc.depthThreshold, 0.0, 1.0);
|
||
|
|
c += mix(color, fragColor, weight) * gaussWeights[i];
|
||
|
|
}
|
||
|
|
|
||
|
|
imageStore(kTextures2DOut[pc.texOut], ivec2(xy), vec4(c, 1.0) );
|
||
|
|
}
|