0be6d925dc
Which means that reduz' beloved style which we all became used to will now be changed automatically to remove the first empty line. This makes us lean closer to 1TBS (the one true brace style) instead of hybridating it with some Allman-inspired spacing. There's still the case of braces around single-statement blocks that needs to be addressed (but clang-format can't help with that, but clang-tidy may if we agree about it). Part of #33027.
243 lines
7.6 KiB
GLSL
243 lines
7.6 KiB
GLSL
/* clang-format off */
|
|
[compute]
|
|
|
|
#version 450
|
|
|
|
VERSION_DEFINES
|
|
|
|
layout(local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
|
|
/* clang-format on */
|
|
|
|
#define FLAG_HORIZONTAL (1 << 0)
|
|
#define FLAG_USE_BLUR_SECTION (1 << 1)
|
|
#define FLAG_USE_ORTHOGONAL_PROJECTION (1 << 2)
|
|
#define FLAG_DOF_NEAR_FIRST_TAP (1 << 3)
|
|
#define FLAG_GLOW_FIRST_PASS (1 << 4)
|
|
#define FLAG_FLIP_Y (1 << 5)
|
|
#define FLAG_FORCE_LUMINANCE (1 << 6)
|
|
#define FLAG_COPY_ALL_SOURCE (1 << 7)
|
|
|
|
layout(push_constant, binding = 1, std430) uniform Params {
|
|
ivec4 section;
|
|
ivec2 target;
|
|
uint flags;
|
|
uint pad;
|
|
// Glow.
|
|
float glow_strength;
|
|
float glow_bloom;
|
|
float glow_hdr_threshold;
|
|
float glow_hdr_scale;
|
|
|
|
float glow_exposure;
|
|
float glow_white;
|
|
float glow_luminance_cap;
|
|
float glow_auto_exposure_grey;
|
|
// DOF.
|
|
float camera_z_far;
|
|
float camera_z_near;
|
|
uint pad2[2];
|
|
}
|
|
params;
|
|
|
|
#ifdef MODE_CUBEMAP_ARRAY_TO_PANORAMA
|
|
layout(set = 0, binding = 0) uniform samplerCubeArray source_color;
|
|
#elif defined(MODE_CUBEMAP_TO_PANORAMA)
|
|
layout(set = 0, binding = 0) uniform samplerCube source_color;
|
|
#else
|
|
layout(set = 0, binding = 0) uniform sampler2D source_color;
|
|
#endif
|
|
|
|
#ifdef GLOW_USE_AUTO_EXPOSURE
|
|
layout(set = 1, binding = 0) uniform sampler2D source_auto_exposure;
|
|
#endif
|
|
|
|
#if defined(MODE_LINEARIZE_DEPTH_COPY) || defined(MODE_SIMPLE_COPY_DEPTH)
|
|
layout(r32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer;
|
|
#elif defined(DST_IMAGE_8BIT)
|
|
layout(rgba8, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer;
|
|
#else
|
|
layout(rgba32f, set = 3, binding = 0) uniform restrict writeonly image2D dest_buffer;
|
|
#endif
|
|
|
|
void main() {
|
|
// Pixel being shaded
|
|
ivec2 pos = ivec2(gl_GlobalInvocationID.xy);
|
|
if (any(greaterThanEqual(pos, params.section.zw))) { //too large, do nothing
|
|
return;
|
|
}
|
|
|
|
#ifdef MODE_MIPMAP
|
|
|
|
ivec2 base_pos = (pos + params.section.xy) << 1;
|
|
vec4 color = texelFetch(source_color, base_pos, 0);
|
|
color += texelFetch(source_color, base_pos + ivec2(0, 1), 0);
|
|
color += texelFetch(source_color, base_pos + ivec2(1, 0), 0);
|
|
color += texelFetch(source_color, base_pos + ivec2(1, 1), 0);
|
|
color /= 4.0;
|
|
|
|
imageStore(dest_buffer, pos + params.target, color);
|
|
#endif
|
|
|
|
#ifdef MODE_GAUSSIAN_BLUR
|
|
|
|
//Simpler blur uses SIGMA2 for the gaussian kernel for a stronger effect
|
|
|
|
if (bool(params.flags & FLAG_HORIZONTAL)) {
|
|
ivec2 base_pos = (pos + params.section.xy) << 1;
|
|
vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.214607;
|
|
color += texelFetch(source_color, base_pos + ivec2(1, 0), 0) * 0.189879;
|
|
color += texelFetch(source_color, base_pos + ivec2(2, 0), 0) * 0.131514;
|
|
color += texelFetch(source_color, base_pos + ivec2(3, 0), 0) * 0.071303;
|
|
color += texelFetch(source_color, base_pos + ivec2(-1, 0), 0) * 0.189879;
|
|
color += texelFetch(source_color, base_pos + ivec2(-2, 0), 0) * 0.131514;
|
|
color += texelFetch(source_color, base_pos + ivec2(-3, 0), 0) * 0.071303;
|
|
imageStore(dest_buffer, pos + params.target, color);
|
|
} else {
|
|
ivec2 base_pos = (pos + params.section.xy);
|
|
vec4 color = texelFetch(source_color, base_pos + ivec2(0, 0), 0) * 0.38774;
|
|
color += texelFetch(source_color, base_pos + ivec2(0, 1), 0) * 0.24477;
|
|
color += texelFetch(source_color, base_pos + ivec2(0, 2), 0) * 0.06136;
|
|
color += texelFetch(source_color, base_pos + ivec2(0, -1), 0) * 0.24477;
|
|
color += texelFetch(source_color, base_pos + ivec2(0, -2), 0) * 0.06136;
|
|
imageStore(dest_buffer, pos + params.target, color);
|
|
}
|
|
#endif
|
|
|
|
#ifdef MODE_GAUSSIAN_GLOW
|
|
|
|
//Glow uses larger sigma 1 for a more rounded blur effect
|
|
|
|
#define GLOW_ADD(m_ofs, m_mult) \
|
|
{ \
|
|
ivec2 ofs = base_pos + m_ofs; \
|
|
if (all(greaterThanEqual(ofs, section_begin)) && all(lessThan(ofs, section_end))) { \
|
|
color += texelFetch(source_color, ofs, 0) * m_mult; \
|
|
} \
|
|
}
|
|
|
|
vec4 color = vec4(0.0);
|
|
|
|
if (bool(params.flags & FLAG_HORIZONTAL)) {
|
|
ivec2 base_pos = (pos + params.section.xy) << 1;
|
|
ivec2 section_begin = params.section.xy << 1;
|
|
ivec2 section_end = section_begin + (params.section.zw << 1);
|
|
|
|
GLOW_ADD(ivec2(0, 0), 0.174938);
|
|
GLOW_ADD(ivec2(1, 0), 0.165569);
|
|
GLOW_ADD(ivec2(2, 0), 0.140367);
|
|
GLOW_ADD(ivec2(3, 0), 0.106595);
|
|
GLOW_ADD(ivec2(-1, 0), 0.165569);
|
|
GLOW_ADD(ivec2(-2, 0), 0.140367);
|
|
GLOW_ADD(ivec2(-3, 0), 0.106595);
|
|
color *= params.glow_strength;
|
|
} else {
|
|
ivec2 base_pos = pos + params.section.xy;
|
|
ivec2 section_begin = params.section.xy;
|
|
ivec2 section_end = section_begin + params.section.zw;
|
|
|
|
GLOW_ADD(ivec2(0, 0), 0.288713);
|
|
GLOW_ADD(ivec2(0, 1), 0.233062);
|
|
GLOW_ADD(ivec2(0, 2), 0.122581);
|
|
GLOW_ADD(ivec2(0, -1), 0.233062);
|
|
GLOW_ADD(ivec2(0, -2), 0.122581);
|
|
color *= params.glow_strength;
|
|
}
|
|
|
|
#undef GLOW_ADD
|
|
|
|
if (bool(params.flags & FLAG_GLOW_FIRST_PASS)) {
|
|
#ifdef GLOW_USE_AUTO_EXPOSURE
|
|
|
|
color /= texelFetch(source_auto_exposure, ivec2(0, 0), 0).r / params.glow_auto_exposure_grey;
|
|
#endif
|
|
color *= params.glow_exposure;
|
|
|
|
float luminance = max(color.r, max(color.g, color.b));
|
|
float feedback = max(smoothstep(params.glow_hdr_threshold, params.glow_hdr_threshold + params.glow_hdr_scale, luminance), params.glow_bloom);
|
|
|
|
color = min(color * feedback, vec4(params.glow_luminance_cap));
|
|
}
|
|
|
|
imageStore(dest_buffer, pos + params.target, color);
|
|
|
|
#endif
|
|
|
|
#ifdef MODE_SIMPLE_COPY
|
|
|
|
vec4 color;
|
|
if (bool(params.flags & FLAG_COPY_ALL_SOURCE)) {
|
|
vec2 uv = vec2(pos) / vec2(params.section.zw);
|
|
if (bool(params.flags & FLAG_FLIP_Y)) {
|
|
uv.y = 1.0 - uv.y;
|
|
}
|
|
color = textureLod(source_color, uv, 0.0);
|
|
|
|
if (bool(params.flags & FLAG_FORCE_LUMINANCE)) {
|
|
color.rgb = vec3(max(max(color.r, color.g), color.b));
|
|
}
|
|
imageStore(dest_buffer, pos + params.target, color);
|
|
|
|
} else {
|
|
color = texelFetch(source_color, pos + params.section.xy, 0);
|
|
|
|
if (bool(params.flags & FLAG_FORCE_LUMINANCE)) {
|
|
color.rgb = vec3(max(max(color.r, color.g), color.b));
|
|
}
|
|
|
|
if (bool(params.flags & FLAG_FLIP_Y)) {
|
|
pos.y = params.section.w - pos.y - 1;
|
|
}
|
|
|
|
imageStore(dest_buffer, pos + params.target, color);
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef MODE_SIMPLE_COPY_DEPTH
|
|
|
|
vec4 color = texelFetch(source_color, pos + params.section.xy, 0);
|
|
|
|
if (bool(params.flags & FLAG_FLIP_Y)) {
|
|
pos.y = params.section.w - pos.y - 1;
|
|
}
|
|
|
|
imageStore(dest_buffer, pos + params.target, vec4(color.r));
|
|
|
|
#endif
|
|
|
|
#ifdef MODE_LINEARIZE_DEPTH_COPY
|
|
|
|
float depth = texelFetch(source_color, pos + params.section.xy, 0).r;
|
|
depth = depth * 2.0 - 1.0;
|
|
depth = 2.0 * params.camera_z_near * params.camera_z_far / (params.camera_z_far + params.camera_z_near - depth * (params.camera_z_far - params.camera_z_near));
|
|
vec4 color = vec4(depth / params.camera_z_far);
|
|
|
|
if (bool(params.flags & FLAG_FLIP_Y)) {
|
|
pos.y = params.section.w - pos.y - 1;
|
|
}
|
|
|
|
imageStore(dest_buffer, pos + params.target, color);
|
|
#endif
|
|
|
|
#if defined(MODE_CUBEMAP_TO_PANORAMA) || defined(MODE_CUBEMAP_ARRAY_TO_PANORAMA)
|
|
|
|
const float PI = 3.14159265359;
|
|
vec2 uv = vec2(pos) / vec2(params.section.zw);
|
|
uv.y = 1.0 - uv.y;
|
|
float phi = uv.x * 2.0 * PI;
|
|
float theta = uv.y * PI;
|
|
|
|
vec3 normal;
|
|
normal.x = sin(phi) * sin(theta) * -1.0;
|
|
normal.y = cos(theta);
|
|
normal.z = cos(phi) * sin(theta) * -1.0;
|
|
|
|
#ifdef MODE_CUBEMAP_TO_PANORAMA
|
|
vec4 color = textureLod(source_color, normal, params.camera_z_far); //the biggest the lod the least the acne
|
|
#else
|
|
vec4 color = textureLod(source_color, vec4(normal, params.camera_z_far), 0.0); //the biggest the lod the least the acne
|
|
#endif
|
|
imageStore(dest_buffer, pos + params.target, color);
|
|
#endif
|
|
}
|