33909a51cd
Build all / build_linux (, ${{ vars.SELF_HOSTED && 'orca-lnx-server' || 'ubuntu-24.04' }}) (push) Has been cancelled
Build all / build_linux (aarch64, ubuntu-24.04-arm) (push) Has been cancelled
Build all / Build Windows arm64 (push) Has been cancelled
Build all / Build Windows x64 (push) Has been cancelled
Build all / build_macos_arch (arm64) (push) Has been cancelled
Build all / build_macos_arch (x86_64) (push) Has been cancelled
Build all / Build macOS Universal (push) Has been cancelled
Build all / Linux x86_64 (push) Has been cancelled
Build all / Linux aarch64 (push) Has been cancelled
Build all / Windows x64 (push) Has been cancelled
Build all / Windows arm64 (push) Has been cancelled
Build all / macOS arm64 (push) Has been cancelled
Build all / Slice check (Linux aarch64) (push) Has been cancelled
Build all / Publish Test Results (push) Has been cancelled
Build all / Flatpak (map[arch:aarch64 runner:ubuntu-24.04-arm]) (push) Has been cancelled
Build all / Flatpak (map[arch:x86_64 runner:ubuntu-24.04]) (push) Has been cancelled
* Fix external outline * Format and values * frag_color -> gl_FragColor * Remove Transform3d& view_matrix * Clarify rendering comments in 3DScene.cpp Updated comments to clarify rendering process using stencil buffer. --------- Co-authored-by: Ian Bassi <ian.bassi@outlook.com> Co-authored-by: Noisyfox <timemanager.rick@gmail.com>
108 lines
3.7 KiB
GLSL
108 lines
3.7 KiB
GLSL
#version 140
|
|
|
|
/**
|
|
* SSAO Shader - GLSL 140 version with sharp depth threshold
|
|
* Only darkens valleys/concave areas, ignores smooth variations
|
|
*/
|
|
|
|
uniform sampler2D color_texture;
|
|
uniform sampler2D depth_texture;
|
|
uniform sampler2D normal_texture;
|
|
uniform float z_near;
|
|
uniform float z_far;
|
|
uniform bool is_outline;
|
|
|
|
in vec2 tex_coord;
|
|
out vec4 frag_color;
|
|
|
|
float linearize_depth(float depth)
|
|
{
|
|
float z = depth * 2.0 - 1.0;
|
|
return (2.0 * z_near * z_far) / (z_far + z_near - z * (z_far - z_near));
|
|
}
|
|
|
|
void main()
|
|
{
|
|
if (is_outline) {
|
|
frag_color = vec4(texture(color_texture, tex_coord).rgb, 1.0);
|
|
return;
|
|
}
|
|
ivec2 pixel = ivec2(gl_FragCoord.xy);
|
|
float center_depth = linearize_depth(texelFetch(depth_texture, pixel, 0).r);
|
|
|
|
// Sample normal buffer (stored as RGB in 0-1 range, convert to -1 to 1)
|
|
vec3 normal_center = texelFetch(normal_texture, pixel, 0).rgb * 2.0 - 1.0;
|
|
normal_center = normalize(normal_center);
|
|
|
|
// Calculate upward-facing factor (Z-up coordinate system)
|
|
float up_factor = clamp(normal_center.z * 1.5, 0.0, 1.0);
|
|
|
|
// Adaptive radius in pixel space
|
|
int radius = int(mix(2.0, 4.0, center_depth / z_far));
|
|
|
|
// Optimized sampling pattern
|
|
const ivec2 offsets[12] = ivec2[](
|
|
ivec2(1, 0), ivec2(-1, 0), ivec2(0, 1), ivec2(0, -1),
|
|
ivec2(1, 1), ivec2(-1, 1), ivec2(1, -1), ivec2(-1, -1),
|
|
ivec2(2, 0), ivec2(-2, 0), ivec2(0, 2), ivec2(0, -2)
|
|
);
|
|
|
|
float occlusion = 0.0;
|
|
int valid_samples = 0;
|
|
|
|
for (int i = 0; i < 12; i++) {
|
|
ivec2 sample_pixel = pixel + offsets[i] * radius;
|
|
|
|
if (sample_pixel.x < 0 || sample_pixel.y < 0)
|
|
continue;
|
|
|
|
float sample_depth = linearize_depth(texelFetch(depth_texture, sample_pixel, 0).r);
|
|
|
|
// Sample normal at neighbor
|
|
vec3 normal_sample = texelFetch(normal_texture, sample_pixel, 0).rgb * 2.0 - 1.0;
|
|
|
|
// Depth difference (positive if neighbor is closer to camera)
|
|
float depth_diff = center_depth - sample_depth;
|
|
|
|
// Sharp depth threshold ===
|
|
// Minimum depth difference to consider occlusion (ignores small variations)
|
|
float threshold_min = 0.008; // Higher = only deep valleys get darkened
|
|
float threshold_max = 0.04; // Transition range for full occlusion
|
|
|
|
float contribution = 0.0;
|
|
if (depth_diff > threshold_min) {
|
|
// Abrupt mapping with power curve
|
|
contribution = (depth_diff - threshold_min) / (threshold_max - threshold_min);
|
|
contribution = clamp(contribution, 0.0, 1.0);
|
|
contribution = pow(contribution, 2.0); // Steeper curve for sharper transition
|
|
}
|
|
|
|
// Reduce occlusion on planar surfaces (similar normals)
|
|
float normal_similarity = dot(normal_center, normal_sample);
|
|
float planar_factor = smoothstep(0.75, 0.95, normal_similarity);
|
|
contribution *= (1.0 - planar_factor * 0.6);
|
|
|
|
occlusion += contribution;
|
|
valid_samples++;
|
|
}
|
|
|
|
if (valid_samples > 0) {
|
|
// Calculate ambient occlusion factor with higher base intensity
|
|
float ao_factor = 1.0 - (occlusion / float(valid_samples)) * 0.6;
|
|
|
|
// Keep bright areas clean (higher minimum for upward-facing surfaces)
|
|
float ao_min = mix(0.55, 0.85, up_factor);
|
|
ao_factor = clamp(ao_factor, ao_min, 1.0);
|
|
|
|
// Slight brightness boost for upward-facing surfaces
|
|
float brightness_boost = 1.0 + up_factor * 0.15;
|
|
ao_factor = ao_factor * brightness_boost;
|
|
|
|
occlusion = ao_factor;
|
|
} else {
|
|
occlusion = 1.0;
|
|
}
|
|
|
|
vec3 color = texture(color_texture, tex_coord).rgb;
|
|
frag_color = vec4(color * occlusion, 1.0);
|
|
} |