diff options
Diffstat (limited to 'apps/openmb/resources/shaders/ssao.frag')
| -rw-r--r-- | apps/openmb/resources/shaders/ssao.frag | 76 |
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; +} |