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.
117 lines
3.6 KiB
GLSL
117 lines
3.6 KiB
GLSL
/* clang-format off */
|
|
[vertex]
|
|
|
|
layout(location = 0) in highp vec4 vertex_attrib;
|
|
/* clang-format on */
|
|
|
|
void main() {
|
|
gl_Position = vertex_attrib;
|
|
gl_Position.z = 1.0;
|
|
}
|
|
|
|
/* clang-format off */
|
|
[fragment]
|
|
|
|
uniform sampler2D source_ssao; //texunit:0
|
|
/* clang-format on */
|
|
uniform sampler2D source_depth; //texunit:1
|
|
uniform sampler2D source_normal; //texunit:3
|
|
|
|
layout(location = 0) out float visibility;
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Tunable Parameters:
|
|
|
|
/** Increase to make depth edges crisper. Decrease to reduce flicker. */
|
|
uniform float edge_sharpness;
|
|
|
|
/** Step in 2-pixel intervals since we already blurred against neighbors in the
|
|
first AO pass. This constant can be increased while R decreases to improve
|
|
performance at the expense of some dithering artifacts.
|
|
|
|
Morgan found that a scale of 3 left a 1-pixel checkerboard grid that was
|
|
unobjectionable after shading was applied but eliminated most temporal incoherence
|
|
from using small numbers of sample taps.
|
|
*/
|
|
|
|
uniform int filter_scale;
|
|
|
|
/** Filter radius in pixels. This will be multiplied by SCALE. */
|
|
#define R (4)
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
// Gaussian coefficients
|
|
const float gaussian[R + 1] =
|
|
//float[](0.356642, 0.239400, 0.072410, 0.009869);
|
|
//float[](0.398943, 0.241971, 0.053991, 0.004432, 0.000134); // stddev = 1.0
|
|
float[](0.153170, 0.144893, 0.122649, 0.092902, 0.062970); // stddev = 2.0
|
|
//float[](0.111220, 0.107798, 0.098151, 0.083953, 0.067458, 0.050920, 0.036108); // stddev = 3.0
|
|
|
|
/** (1, 0) or (0, 1)*/
|
|
uniform ivec2 axis;
|
|
|
|
uniform float camera_z_far;
|
|
uniform float camera_z_near;
|
|
|
|
uniform ivec2 screen_size;
|
|
|
|
void main() {
|
|
ivec2 ssC = ivec2(gl_FragCoord.xy);
|
|
|
|
float depth = texelFetch(source_depth, ssC, 0).r;
|
|
//vec3 normal = texelFetch(source_normal,ssC,0).rgb * 2.0 - 1.0;
|
|
|
|
depth = depth * 2.0 - 1.0;
|
|
depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - depth * (camera_z_far - camera_z_near));
|
|
|
|
float depth_divide = 1.0 / camera_z_far;
|
|
|
|
//depth *= depth_divide;
|
|
|
|
/*
|
|
if (depth > camera_z_far * 0.999) {
|
|
discard; //skybox
|
|
}
|
|
*/
|
|
|
|
float sum = texelFetch(source_ssao, ssC, 0).r;
|
|
|
|
// Base weight for depth falloff. Increase this for more blurriness,
|
|
// decrease it for better edge discrimination
|
|
float BASE = gaussian[0];
|
|
float totalWeight = BASE;
|
|
sum *= totalWeight;
|
|
|
|
ivec2 clamp_limit = screen_size - ivec2(1);
|
|
|
|
for (int r = -R; r <= R; ++r) {
|
|
// We already handled the zero case above. This loop should be unrolled and the static branch optimized out,
|
|
// so the IF statement has no runtime cost
|
|
if (r != 0) {
|
|
ivec2 ppos = ssC + axis * (r * filter_scale);
|
|
float value = texelFetch(source_ssao, clamp(ppos, ivec2(0), clamp_limit), 0).r;
|
|
ivec2 rpos = clamp(ppos, ivec2(0), clamp_limit);
|
|
float temp_depth = texelFetch(source_depth, rpos, 0).r;
|
|
//vec3 temp_normal = texelFetch(source_normal, rpos, 0).rgb * 2.0 - 1.0;
|
|
|
|
temp_depth = temp_depth * 2.0 - 1.0;
|
|
temp_depth = 2.0 * camera_z_near * camera_z_far / (camera_z_far + camera_z_near - temp_depth * (camera_z_far - camera_z_near));
|
|
// temp_depth *= depth_divide;
|
|
|
|
// spatial domain: offset gaussian tap
|
|
float weight = 0.3 + gaussian[abs(r)];
|
|
//weight *= max(0.0,dot(temp_normal,normal));
|
|
|
|
// range domain (the "bilateral" weight). As depth difference increases, decrease weight.
|
|
weight *= max(0.0, 1.0 - edge_sharpness * abs(temp_depth - depth));
|
|
|
|
sum += value * weight;
|
|
totalWeight += weight;
|
|
}
|
|
}
|
|
|
|
const float epsilon = 0.0001;
|
|
visibility = sum / (totalWeight + epsilon);
|
|
}
|