LYGIA Shader Library

ao (lygia/lighting/raymarch/ao)

Calculate Ambient Occlusion. See calcAO in https://www.shadertoy.com/view/lsKcDD

Dependencies:

Use:

<float> raymarchAO( in <vec3> pos, in <vec3> nor )

Check it on Github



#ifndef RAYMARCH_AO_SAMPLES
#define RAYMARCH_AO_SAMPLES 5
#endif

#ifndef RAYMARCH_AO_INTENSITY
#define RAYMARCH_AO_INTENSITY 1.0
#endif

#ifndef RAYMARCH_AO_MIN_DIST
#define RAYMARCH_AO_MIN_DIST 0.001
#endif

#ifndef RAYMARCH_AO_MAX_DIST
#define RAYMARCH_AO_MAX_DIST 0.2
#endif

#ifndef RAYMARCH_AO_FALLOFF
#define RAYMARCH_AO_FALLOFF 0.95
#endif

#ifndef FNC_RAYMARCH_AO
#define FNC_RAYMARCH_AO

float raymarchAO(in vec3 pos, in vec3 nor) {
    float occ = 0.0;
    float sca = 1.0;
    const float samplesFactor = 1.0 / float(RAYMARCH_AO_SAMPLES-1);
    for (int i = 0; i < RAYMARCH_AO_SAMPLES; i++) {
        float h = RAYMARCH_AO_MIN_DIST + RAYMARCH_AO_MAX_DIST * float(i) * samplesFactor;
        float d = RAYMARCH_MAP_FNC(pos + h * nor).sdf;
        occ += (h - d) * sca;
        sca *= RAYMARCH_AO_FALLOFF;
    }
    return saturate(1.0 - RAYMARCH_AO_INTENSITY * occ);
}

#endif

Dependencies:

Use:

<float> raymarchAO( in <float3> pos, in <float3> nor )

Check it on Github



#ifndef RAYMARCH_AO_SAMPLES
#define RAYMARCH_AO_SAMPLES 5
#endif

#ifndef RAYMARCH_AO_INTENSITY
#define RAYMARCH_AO_INTENSITY 1.0
#endif

#ifndef RAYMARCH_AO_MIN_DIST
#define RAYMARCH_AO_MIN_DIST 0.001
#endif

#ifndef RAYMARCH_AO_MAX_DIST
#define RAYMARCH_AO_MAX_DIST 0.2
#endif

#ifndef RAYMARCH_AO_FALLOFF
#define RAYMARCH_AO_FALLOFF 0.95
#endif

#ifndef FNC_RAYMARCH_AO
#define FNC_RAYMARCH_AO

float raymarchAO(in float3 pos, in float3 nor) {
    float occ = 0.0;
    float sca = 1.0;
    const float samplesFactor = 1.0 / float(RAYMARCH_AO_SAMPLES-1);
    for (int i = 0; i < RAYMARCH_AO_SAMPLES; i++) {
        float h = RAYMARCH_AO_MIN_DIST + RAYMARCH_AO_MAX_DIST * float(i) * samplesFactor;
        float d = RAYMARCH_MAP_FNC(pos + h * nor).sdf;
        occ += (h - d) * sca;
        sca *= RAYMARCH_AO_FALLOFF;
    }
    return saturate(1.0 - RAYMARCH_AO_INTENSITY * occ);
}

#endif

Dependencies:

Use:

<float> raymarchAO( in <float3> pos, in <float3> nor )

Check it on Github



#ifndef RAYMARCH_SAMPLES_AO
#define RAYMARCH_SAMPLES_AO 5
#endif

#ifndef RAYMARCH_MAP_FNC
#define RAYMARCH_MAP_FNC(POS) raymarchMap(POS)
#endif

#ifndef RAYMARCH_MAP_DISTANCE
#define RAYMARCH_MAP_DISTANCE w
#endif

#ifndef FNC_RAYMARCH_AO
#define FNC_RAYMARCH_AO

inline __host__ __device__ float raymarchAO(const float3& pos, const float3& nor ) {
    float occ = 0.0f;
    float sca = 1.0f;
    for( int i = 0; i < RAYMARCH_SAMPLES_AO; i++ ) {
        float hr = 0.01f + 0.12f * float(i) * 0.2f;
        float dd = RAYMARCH_MAP_FNC( hr * nor + pos ).RAYMARCH_MAP_DISTANCE;
        occ += (hr - dd) * sca;
        sca *= 0.9f;
        if( occ > 0.35f ) 
            break;
    }
    return clamp( 1.0f - 3.0f * occ, 0.0f, 1.0f) * (0.5f + 0.5f * nor.y);
}

#endif

Examples

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.

Get the latest news and releases

Sign up for the news letter bellow, joing the LYGIA's channel on Discord or follow the Github repository