added simple ssao shader

Commit 6f99fed14ef3 · silentevermore · 2026-10-20 22:04 +0300

Changeset
6f99fed14ef305cb84472cf3fc674ce045a24d9f

View source at this commit

Comments

No comments yet.

Log in to comment

Diff

diff --git a/shaders/post.glsl b/shaders/post.glsl
--- a/shaders/post.glsl
+++ b/shaders/post.glsl
@@ -3,11 +3,14 @@
 in vec3 fragPosition;
 in vec3 fragNormal;
 in vec2 fragTexCoord;
+in vec4 fragColor;
 
 uniform sampler2D texture0;
+uniform sampler2D depth_tex;
 
 out vec4 finalColor;
 
+// dither
 const mat4 bayerMatrix = mat4(
 		0.0/16.0, 12.0/16.0,  3.0/16.0, 15.0/16.0,
 		8.0/16.0,  4.0/16.0, 11.0/16.0,  7.0/16.0,
@@ -15,11 +18,35 @@
 		10.0/16.0,  6.0/16.0,  9.0/16.0,  5.0/16.0
 );
 
+// ssao
+const vec2 OFFSETS[8] = vec2[8](
+    vec2( 1.0,  0.0),
+    vec2(-1.0,  0.0),
+    vec2( 0.0,  1.0),
+    vec2( 0.0, -1.0),
+    vec2( 0.707,  0.707),
+    vec2(-0.707,  0.707),
+    vec2( 0.707, -0.707),
+    vec2(-0.707, -0.707)
+);
+
+// pixelization + other
 float pixel_size = 1.0;
 float contrast = 1.5;
 float levels = 32.0;
 vec2 gamma = vec2(0.5, 1.5);
 
+// isoteric.
+const float near_plane = 0.01;
+const float far_plane = 1000.0;
+const float fog_far = 150.0;
+
+float linearize_depth(float d) {
+	float z = d * 2.0 - 1.0;
+	float lin = (2.0 * near_plane * far_plane) / (far_plane + near_plane - z * (far_plane - near_plane));
+	return clamp(lin / fog_far, 0.0, 1.0);
+}
+
 void main() {
 	// pixelization
 	vec2 texsize = textureSize(texture0, 0);
@@ -28,10 +55,11 @@
 
 	vec2 p = pixel_uv - vec2(0.5);
 	float r = length(p);
-	vec2 dist = p / (1.0 + 0.25 * r);
+	vec2 dist = p * (1.0 + 0.25 * r);
 	pixel_uv = dist * 0.5 + vec2(0.5);
 
-	vec4 color = texture(texture0, pixel_uv);
+	float depth = texture(depth_tex, pixel_uv).r;
+	vec4 color = texture(texture0, pixel_uv) * fragColor;
 
 	// dither
 	{
@@ -57,6 +85,64 @@
 	// vignette
 	float diff = length(fragTexCoord - vec2(0.5));
 	color.rgb *= 1.0 - diff;
+	color.rgb *= pow(1.0 - linearize_depth(depth), 4.0);
 
+	if (depth < 1) {
+		float strength = 1.0;
+		float radius = 4.0;
+		int ao_idx = 1;
+
+		// ssao
+		if (ao_idx == 1) {
+			// simple
+			vec2 px = radius / texsize;
+		    float ao = 0.0;
+
+		    float d1 = texture(depth_tex, pixel_uv + vec2( px.x, 0.0)).r;
+		    float d2 = texture(depth_tex, pixel_uv + vec2(-px.x, 0.0)).r;
+		    float d3 = texture(depth_tex, pixel_uv + vec2(0.0,  px.y)).r;
+		    float d4 = texture(depth_tex, pixel_uv + vec2(0.0, -px.y)).r;
+
+		    ao += smoothstep(0.001, 0.008, depth - d1);
+		    ao += smoothstep(0.001, 0.008, depth - d2);
+		    ao += smoothstep(0.001, 0.008, depth - d3);
+		    ao += smoothstep(0.001, 0.008, depth - d4);
+		    ao *= 0.25;
+		    
+			color.rgb *= 1.0 - ao * strength;
+		} else {
+			float occlusion = 0.0;
+		    vec2 texelSize = 1.0 / texsize;
+
+		    for (int i = 0; i < 8; i++) {
+		        vec2 sampleUV =
+		            pixel_uv + OFFSETS[i] * radius * texelSize;
+
+		        if (any(lessThan(sampleUV, vec2(0.0))) ||
+		            any(greaterThan(sampleUV, vec2(1.0)))) continue;
+
+		        float sampleDepth = texture(depth_tex, sampleUV).r;
+
+		        if (sampleDepth >= 0.99999) continue;
+
+		        float difference = depth - sampleDepth;
+		        float bias = max(0.0005, depth * 0.002);
+
+		        occlusion += smoothstep(
+		            bias,
+		            bias * 4.0,
+		            difference
+		        );
+		    }
+
+		    float ao = clamp(
+		        1.0 - strength * (occlusion / 8.0),
+		        0.0,
+		        1.0
+		    );
+
+			color.rgb *= ao;
+		}
+	}
 	finalColor = color;
 }