lygia
/v1.1.6
/lighting
/ssao
)ScreenSpace Ambient Occlusion
Dependencies:
lygia
/v1.1.6
/math
/saturate
.glsl
lygia
/v1.1.6
/space
/linearizeDepth
.glsl
lygia
/v1.1.6
/space
/depth2viewZ
.glsl
lygia
/v1.1.6
/sample
.glsl
lygia
/v1.1.6
/generative
/random
.glsl
Use:
<float> ssao(<SAMPLER_TYPE> texPosition, <SAMPLER_TYPE> texNormal, vec2 <st> [, <float> radius, float <bias>])
#ifndef SSAO_SAMPLES_NUM
#define SSAO_SAMPLES_NUM 8
#endif
#ifndef SSAO_SAMPLES_ARRAY
#if defined(GLSLVIEWER)
#define SSAO_SAMPLES_ARRAY u_ssaoSamples
uniform vec3 u_ssaoSamples[SSAO_SAMPLES_NUM];
#endif
#endif
#ifndef SSAO_NOISE_NUM
#define SSAO_NOISE_NUM 4
#endif
#ifndef SSAO_NOISE_ARRAY
#if defined(GLSLVIEWER)
#define SSAO_NOISE_ARRAY u_ssaoNoise
uniform vec3 u_ssaoNoise[SSAO_NOISE_NUM];
#endif
#endif
#ifndef CAMERA_PROJECTION_MATRIX
#if defined(GLSLVIEWER)
#define CAMERA_PROJECTION_MATRIX u_projectionMatrix
#else
#define CAMERA_PROJECTION_MATRIX u_projection
#endif
#endif
#ifndef SSAO_NOISE2_FNC
#define SSAO_NOISE2_FNC(ST) random2(ST)
#endif
#ifndef SSAO_NOISE3_FNC
#define SSAO_NOISE3_FNC(POS) random3(POS)
#endif
#ifndef SSAO_DEPTH_BIAS
#define SSAO_DEPTH_BIAS 0.05
#endif
#ifndef FNC_SSAO
#define FNC_SSAO
#if defined(CAMERA_NEAR_CLIP) && defined(CAMERA_FAR_CLIP)
float ssao(SAMPLER_TYPE texDepth, vec2 st, vec2 pixel, float radius) {
#if defined(SSAO_NOISE_ARRAY)
float noiseS = sqrt(float(SSAO_NOISE_NUM));
int noiseX = int( mod(gl_FragCoord.x - 0.5, noiseS) );
int noiseY = int( mod(gl_FragCoord.y - 0.5, noiseS) );
vec2 noise = SSAO_NOISE_ARRAY[noiseX + noiseY * int(noiseS)].xy;
#else
vec2 noise = SSAO_NOISE2_FNC( st );
#endif
noise *= 0.1;
float depth = depth2viewZ( SAMPLER_FNC( texDepth, st ).r ) + SSAO_DEPTH_BIAS * 0.5;
float ao = 0.0;
// if (depth < 0.99)
{
float w = pixel.x / depth + noise.x;
float h = pixel.y / depth + noise.y;
float dz = 1.0 / float( SSAO_SAMPLES_NUM );
float l = 0.0;
float z = 1.0 - dz * 0.5;
for ( int i = 0; i < SSAO_SAMPLES_NUM; i ++ ) {
float r = sqrt( 1.0 - z );
float pw = cos( l ) * r;
float ph = sin( l ) * r;
vec2 vv = radius * vec2( pw * w, ph * h);
ao += ( step( depth2viewZ( SAMPLER_FNC( texDepth, st + vv).r ), depth) +
step( depth2viewZ( SAMPLER_FNC( texDepth, st - vv).r ), depth) ) * 0.5;
z = z - dz;
l = l + 2.399963229728653;
}
ao = 1.0 - ao * dz;
ao = saturate( 1.98 * ( 1.0 - ao ) );
}
return ao;
}
#endif
#if defined(SSAO_SAMPLES_ARRAY)
float ssao(SAMPLER_TYPE texPosition, SAMPLER_TYPE texNormal, vec2 st, float radius) {
vec4 position = SAMPLER_FNC(texPosition, st);
vec3 normal = SAMPLER_FNC(texNormal, st).rgb;
#if defined(SSAO_NOISE_ARRAY)
float noiseS = sqrt(float(SSAO_NOISE_NUM));
int noiseX = int( mod(gl_FragCoord.x - 0.5, noiseS) );
int noiseY = int( mod(gl_FragCoord.y - 0.5, noiseS) );
vec3 noise = SSAO_NOISE_ARRAY[noiseX + noiseY * int(noiseS)];
#else
vec3 noise = SSAO_NOISE3_FNC( position.xyz );
#endif
vec3 tangent = normalize(noise - normal * dot(noise, normal));
vec3 binormal = cross(normal, tangent);
mat3 tbn = mat3(tangent, binormal, normal);
float occlusion = 0.0;
for (int i = 0; i < SSAO_SAMPLES_NUM; ++i) {
vec3 samplePosition = tbn * SSAO_SAMPLES_ARRAY[i];
samplePosition = position.xyz + samplePosition * radius;
vec4 offsetUV = vec4(samplePosition, 1.0);
offsetUV = CAMERA_PROJECTION_MATRIX * offsetUV;
offsetUV.xy /= offsetUV.w;
offsetUV.xy = offsetUV.xy * 0.5 + 0.5;
float sampleDepth = SAMPLER_FNC(texPosition, offsetUV.xy).z;
float rangeCheck = smoothstep(0.0, 1.0, radius / abs(position.z - sampleDepth));
occlusion += (sampleDepth >= samplePosition.z + SSAO_DEPTH_BIAS ? 1.0 : 0.0) * rangeCheck;
}
occlusion /= float(SSAO_SAMPLES_NUM);
return 1.0-occlusion;
}
#endif
#endif
LYGIA is dual-licensed under the Prosperity License and the Patron License for sponsors and contributors.
Sponsors and contributors are automatically added to the Patron License and they can ignore the any non-commercial rule of the Prosperity Licensed software (please take a look to the exception).
It's also possible to get a permanent comercial license hook to a single and specific version of LYGIA.
Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository