aboutsummaryrefslogtreecommitdiff
path: root/apps/openmb/resources/shaders/ssao.frag
diff options
context:
space:
mode:
authorEthan Morgan <ethan@gweithio.com>2026-02-14 16:44:06 +0000
committerEthan Morgan <ethan@gweithio.com>2026-02-14 16:44:06 +0000
commit54409423f767d8b1cf30cb7d0efca6b4ca138823 (patch)
treed915ac7828703ce4b963efdd9728a1777ba18c1e /apps/openmb/resources/shaders/ssao.frag
move to own git serverHEADmaster
Diffstat (limited to 'apps/openmb/resources/shaders/ssao.frag')
-rw-r--r--apps/openmb/resources/shaders/ssao.frag76
1 files changed, 76 insertions, 0 deletions
diff --git a/apps/openmb/resources/shaders/ssao.frag b/apps/openmb/resources/shaders/ssao.frag
new file mode 100644
index 0000000..60479f2
--- /dev/null
+++ b/apps/openmb/resources/shaders/ssao.frag
@@ -0,0 +1,76 @@
+#version 330 core
+in vec2 vUV;
+out float FragColor;
+
+uniform sampler2D gDepth;
+uniform sampler2D gNormal;
+uniform sampler2D texNoise;
+
+uniform vec3 samples[64];
+uniform mat4 proj;
+uniform mat4 invProj;
+uniform float radius;
+uniform float bias;
+uniform float noiseScale;
+
+uniform int kernelSize;
+uniform float power;
+
+vec3 getViewPos(vec2 uv)
+{
+ float depth = texture(gDepth, uv).r;
+ if (depth == 1.0) return vec3(0.0);
+ float z = depth * 2.0 - 1.0;
+ vec4 clip = vec4(uv * 2.0 - 1.0, z, 1.0);
+ vec4 viewPos = invProj * clip;
+ viewPos /= viewPos.w;
+ return viewPos.xyz;
+}
+
+void main()
+{
+ vec3 fragPos = getViewPos(vUV);
+ if (fragPos == vec3(0.0))
+ {
+ FragColor = 1.0;
+ return;
+ }
+
+ vec3 normal = texture(gNormal, vUV).rgb;
+ normal = normalize(normal * 2.0 - 1.0);
+
+ vec3 randomVec = normalize(texture(texNoise, vUV * noiseScale).xyz * 2.0 - 1.0);
+
+
+ vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
+ vec3 bitangent = cross(normal, tangent);
+ mat3 TBN = mat3(tangent, bitangent, normal);
+
+ float occlusion = 0.0;
+ for (int i = 0; i < kernelSize; ++i)
+ {
+ vec3 sample = TBN * samples[i];
+ sample = fragPos + sample * radius;
+
+
+ vec4 offset = proj * vec4(sample, 1.0);
+ offset.xyz /= offset.w;
+ vec2 sampleUV = offset.xy * 0.5 + 0.5;
+
+ if (sampleUV.x < 0.0 || sampleUV.x > 1.0 || sampleUV.y < 0.0 || sampleUV.y > 1.0)
+ continue;
+
+ vec3 samplePos = getViewPos(sampleUV);
+ if (samplePos == vec3(0.0))
+ continue;
+
+ float rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - samplePos.z));
+ float diff = samplePos.z - sample.z;
+ if (diff > bias)
+ occlusion += rangeCheck;
+ }
+
+ occlusion = 1.0 - (occlusion / float(kernelSize));
+ occlusion = pow(occlusion, power);
+ FragColor = occlusion;
+}