124 lines
3.9 KiB
Plaintext
124 lines
3.9 KiB
Plaintext
#version 460
|
|
|
|
#include "noise.glsl"
|
|
|
|
layout(local_size_x = 16, local_size_y = 8, local_size_z = 1) in;
|
|
|
|
layout(set = 0, binding = 0, rgba16f) uniform image2D dest;
|
|
|
|
layout(set = 0, binding = 1, rgba8) uniform image2D src_base_color;
|
|
layout(set = 0, binding = 2, rgba16f) uniform image2D src_diffuse_gi;
|
|
layout(set = 0, binding = 3, rgba16f) uniform image2D src_specular;
|
|
layout(set = 0, binding = 4, rgba16f) uniform image2D src_additive;
|
|
layout(set = 0, binding = 5, rgba16f) uniform image2D src_normals;
|
|
|
|
// Blatantly copypasted from https://www.shadertoy.com/view/XsGfWV
|
|
vec3 aces_tonemap(vec3 color){
|
|
mat3 m1 = mat3(
|
|
0.59719, 0.07600, 0.02840,
|
|
0.35458, 0.90834, 0.13383,
|
|
0.04823, 0.01566, 0.83777
|
|
);
|
|
mat3 m2 = mat3(
|
|
1.60475, -0.10208, -0.00327,
|
|
-0.53108, 1.10813, -0.07276,
|
|
-0.07367, -0.00605, 1.07602
|
|
);
|
|
vec3 v = m1 * color;
|
|
vec3 a = v * (v + 0.0245786) - 0.000090537;
|
|
vec3 b = v * (0.983729 * v + 0.4329510) + 0.238081;
|
|
return pow(clamp(m2 * (a / b), 0.0, 1.0), vec3(1.0 / 2.2));
|
|
}
|
|
|
|
float normpdf2(in float x2, in float sigma) { return 0.39894*exp(-0.5*x2/(sigma*sigma))/sigma; }
|
|
float normpdf(in float x, in float sigma) { return normpdf2(x*x, sigma); }
|
|
|
|
void readNormals(ivec2 uv, out vec3 geometry_normal, out vec3 shading_normal) {
|
|
const vec4 n = imageLoad(src_normals, uv);
|
|
geometry_normal = vec3(n.xy, sqrt(1. - n.x*n.x - n.y*n.y));
|
|
shading_normal = vec3(n.zw, sqrt(1. - n.z*n.z - n.w*n.w));
|
|
}
|
|
|
|
void main() {
|
|
ivec2 res = ivec2(imageSize(src_base_color));
|
|
ivec2 pix = ivec2(gl_GlobalInvocationID);
|
|
|
|
if (any(greaterThanEqual(pix, res))) {
|
|
return;
|
|
}
|
|
|
|
const vec4 base_color = imageLoad(src_base_color, pix);
|
|
const float material_index = imageLoad(src_diffuse_gi, pix).a;
|
|
|
|
//imageStore(dest, pix, vec4(aces_tonemap(base_color.rgb), 0.)); return;
|
|
//imageStore(dest, pix, vec4((base_color.rgb), 0.)); return;
|
|
//imageStore(dest, pix, vec4(aces_tonemap(imageLoad(src_diffuse_gi, pix).rgb), 0.)); return;
|
|
//imageStore(dest, pix, vec4(aces_tonemap(imageLoad(src_specular, pix).rgb), 0.)); return;
|
|
|
|
vec3 geometry_normal, shading_normal;
|
|
readNormals(pix, geometry_normal, shading_normal);
|
|
|
|
//imageStore(dest, pix, vec4(.5 + geometry_normal * .5, 0.)); return;
|
|
|
|
/* const uint mi = uint(material_index); */
|
|
/* imageStore(dest, pix, vec4(rand3_f01(uvec3(mi,mi+1,mi+2)), 0.)); */
|
|
/* return; */
|
|
|
|
const int KERNEL_SIZE = 8;
|
|
float total_scale = 0.;
|
|
float specular_total_scale = 0.;
|
|
vec3 colour = vec3(0.);
|
|
vec3 speculour = vec3(0.);
|
|
for (int x = -KERNEL_SIZE; x <= KERNEL_SIZE; ++x)
|
|
for (int y = -KERNEL_SIZE; y <= KERNEL_SIZE; ++y) {
|
|
const ivec2 p = pix + ivec2(x, y);
|
|
if (any(greaterThanEqual(p, res)) || any(lessThan(p, ivec2(0)))) {
|
|
continue;
|
|
}
|
|
|
|
const vec4 c = imageLoad(src_diffuse_gi, p);
|
|
if (c.a != material_index)
|
|
continue;
|
|
|
|
vec3 sample_geometry_normal, sample_shading_normal;
|
|
readNormals(p, sample_geometry_normal, sample_shading_normal);
|
|
|
|
if ( dot(sample_geometry_normal, geometry_normal) < .99 )
|
|
continue;
|
|
|
|
// TODO bilaterally filter shading normals
|
|
|
|
const float sigma = KERNEL_SIZE / 2.;
|
|
const float scale = normpdf(x, sigma) * normpdf(y, sigma);
|
|
colour += scale * imageLoad(src_diffuse_gi, p).rgb;
|
|
total_scale += scale;
|
|
|
|
const int SPECULAR_KERNEL_SIZE = 2;
|
|
if (all(lessThan(abs(ivec2(x, y)), ivec2(SPECULAR_KERNEL_SIZE)))) {
|
|
const float spigma = SPECULAR_KERNEL_SIZE / 2.;
|
|
const float specuale = normpdf(x, spigma) * normpdf(y, spigma);
|
|
speculour += specuale * imageLoad(src_specular, p).rgb;
|
|
specular_total_scale += specuale;
|
|
}
|
|
}
|
|
|
|
if (total_scale > 0.) {
|
|
colour /= total_scale;
|
|
colour *= base_color.rgb;
|
|
}
|
|
|
|
if (specular_total_scale > 0.) {
|
|
speculour /= specular_total_scale;
|
|
//speculour *= base_color.rgb;
|
|
colour += speculour;
|
|
}
|
|
|
|
//colour += imageLoad(src_specular, pix).rgb;
|
|
colour += imageLoad(src_additive, pix).rgb;
|
|
|
|
colour = aces_tonemap(colour);
|
|
|
|
imageStore(dest, pix, vec4(colour, 0.));
|
|
//imageStore(dest, pix, imageLoad(src_diffuse_gi, pix));
|
|
}
|