Need help modifying SSAO script

I’m using the SSAO script that came with Mike Pan’s Easy Game add on. It is the original Martinsh script, or some version of it. I’d like to modify the script to achieve a stronger feel, as shown in the images. I know nothing of Python, and have played with this script in an attempt to figure it out. I’m just too many hours in, and at this point I’m just wasting time. Help? Thanks.

Image 1 shows the script in game. Image 2 shows Blender’s new built-in ao, which I wish worked in game. I’d like the script to look similar to that setting. Script below.


/*
SSAO GLSL shader v1.2
assembled by Martins Upitis (martinsh) (devlog-martinsh.blogspot.com)
original technique is made by Arkano22 (www.gamedev.net/topic/550699-ssao-no-halo-artifacts/)

*/

uniform sampler2D bgl_DepthTexture;
uniform sampler2D bgl_RenderedTexture;
uniform float bgl_RenderedTextureWidth;
uniform float bgl_RenderedTextureHeight;
uniform float timer;

#define PI 3.14159265

float width = bgl_RenderedTextureWidth; //texture width
float height = bgl_RenderedTextureHeight; //texture height

vec2 texCoord = gl_TexCoord[0].st;

//------------------------------------------
//general stuff

//make sure that these two values are the same for your camera, otherwise distances will be wrong.

float znear = 0.1; //Z-near
float zfar = 100.0; //Z-far

//user variables
int samples = 8; //ao sample count

float radius = 5.0; //ao radius
float aoclamp = 0.25; //depth clamp - reduces haloing at screen edges
bool noise = true; //use noise instead of pattern for sample dithering
float noiseamount = 0.001; //dithering amount

float diffarea = 0.4; //self-shadowing reduction
float gdisplace = 0.4; //gauss bell center

float lumInfluence = 0.5; //how much luminance affects occlusion

//--------------------------------------------------------

vec2 rand(vec2 coord) //generating noise/pattern texture for dithering
{
float noiseX = ((fract(1.0-coord.s*(width/2.0))0.25)+(fract(coord.t(height/2.0))*0.75))2.0-1.0;
float noiseY = ((fract(1.0-coord.s
(width/2.0))0.75)+(fract(coord.t(height/2.0))*0.25))*2.0-1.0;

if (noise)
{
noiseX = clamp(fract(sin(dot(coord ,vec2(20.0,46.0*timer))) * 47358.5453),0.0,1.0)2.0-1.0;
noiseY = clamp(fract(sin(dot(coord ,vec2(41.0,37.2
timer)*2.0)) * 43758.5453),0.0,1.0)*2.0-1.0;
}
return vec2(noiseX,noiseY)*noiseamount;
}

float readDepth(in vec2 coord)
{
if (gl_TexCoord[0].x<0.0||gl_TexCoord[0].y<0.0) return 1.0;
return (2.0 * znear) / (zfar + znear - texture2D(bgl_DepthTexture, coord ).x * (zfar-znear));
}

float compareDepths(in float depth1, in float depth2,inout int far)
{
float garea = 2.0; //gauss bell width
float diff = (depth1 - depth2)*100.0; //depth difference (0-100)
//reduce left bell width to avoid self-shadowing
if (diff<gdisplace)
{
garea = diffarea;
}else{
far = 1;
}

float gauss = pow(2.7182,-2.0*(diff-gdisplace)(diff-gdisplace)/(gareagarea));
return gauss;
}

float calAO(float depth,float dw, float dh)
{
float dd = (1.0-depth)*radius;

float temp = 0.0;
float temp2 = 0.0;
float coordw = gl_TexCoord[0].x + dwdd;
float coordh = gl_TexCoord[0].y + dh
dd;
float coordw2 = gl_TexCoord[0].x - dwdd;
float coordh2 = gl_TexCoord[0].y - dh
dd;

vec2 coord = vec2(coordw , coordh);
vec2 coord2 = vec2(coordw2, coordh2);

int far = 0;
temp = compareDepths(depth, readDepth(coord),far);
//DEPTH EXTRAPOLATION:
if (far > 0)
{
temp2 = compareDepths(readDepth(coord2),depth,far);
temp += (1.0-temp)*temp2;
}

return temp;
}

void main(void)
{
vec2 noise = rand(texCoord);
float depth = readDepth(texCoord);

float w = (1.0 / width)/clamp(depth,aoclamp,1.0)+(noise.x*(1.0-noise.x));
float h = (1.0 / height)/clamp(depth,aoclamp,1.0)+(noise.y*(1.0-noise.y));

float pw;
float ph;

float ao;

float dl = PI*(3.0-sqrt(5.0));
float dz = 1.0/float(samples);
float l = 0.0;
float z = 1.0 - dz/2.0;

for (int i = 0; i <= samples; i ++)
{
float r = sqrt(1.0-z);

pw = cos(l)r;
ph = sin(l)r;
ao += calAO(depth,pw
w,ph
h);
z = z - dz;
l = l + dl;
}

ao /= float(samples);
ao = 1.0-ao;

vec3 color = texture2D(bgl_RenderedTexture,texCoord).rgb;

vec3 lumcoeff = vec3(0.299,0.587,0.114);
float lum = dot(color.rgb, lumcoeff);
vec3 luminance = vec3(lum, lum, lum);

vec3 final = vec3(colormix(vec3(ao),vec3(1.0),luminancelumInf luence));

gl_FragColor = vec4(final,1.0);

}

Attachments



Bumpity bump. It’s gonna be a bumpy road…

Sorry, last chance at a bumpity bump.

That is not python at all. You should probably post this in the game engine support forum instead.

Ahh, ok. It’s a .glsl script. Thanks.

Ok, I moved it to the Game Engine Support Forum. This is a GLSL script. Thanks in advance.

I’m now working from this updated script, which looks a lot better. I’ve figured out some things to make it look stronger, but if anyone has any ideas to make it stronger, I’d welcome them.

/*SSAO GLSL shader v1.3
assembled by Martins Upitis (martinsh) (devlog-martinsh.blogspot.com)
original technique is made by Arkano22 (www.gamedev.net/topic/550699-ssao-no-halo-artifacts/)

changelog:
1.3 - heavy optimization - varying sample count and ao density areas based on luminance
1.2 - added fog calculation to mask AO. Minor fixes.
1.1 - added spiral sampling method from here:
(http://www.cgafaq.info/wiki/Evenly_distributed_points_on_sphere)
*/
uniform sampler2D bgl_DepthTexture;
uniform sampler2D bgl_RenderedTexture;
uniform float bgl_RenderedTextureWidth;
uniform float bgl_RenderedTextureHeight;
//uniform float timer;

#define PI 3.14159265

float width = bgl_RenderedTextureWidth; //texture width
float height = bgl_RenderedTextureHeight; //texture height

vec2 texCoord = gl_TexCoord[0].st;

//------------------------------------------
//general stuff

//make sure that these two values are the same for your camera, otherwise distances will be wrong.

float znear = 0.1; //Z-near
float zfar = 75.0; //Z-far

//user variables
int samples = 64; //ao sample count
bool optimize = true;
int minsamples = 2;

float radius = 2.0; //ao radius
float aoclamp = 0.1; //depth clamp - reduces haloing at screen edges
bool noise = false; //use noise instead of pattern for sample dithering
float noiseamount = 0.001; //dithering amount

float diffarea = 0.1; //self-shadowing reduction
float gdisplace = 0.06; //gauss bell center
float aowidth = 0.09; //gauss bell width

bool mist = true; //use mist?
float miststart = 0.0; //mist start
float mistend = 100.0; //mist end

bool onlyAO = false; //use only ambient occlusion pass?
float lumInfluence = 0.5; //how much luminance affects occlusion

//--------------------------------------------------------

float doMist()
{
float zdepth = texture2D(bgl_DepthTexture,texCoord.xy).x;
float depth = -zfar * znear / (zdepth * (zfar - znear) - zfar);
return clamp((depth-miststart)/mistend,0.0,1.0);
}

vec2 rand(vec2 coord) //generating noise/pattern texture for dithering
{

    float noiseX = ((fract(1.0-coord.s*(width/2.0))*0.25)+(fract(coord.t*(height/2.0))*0.75))*2.0-1.0;
    float noiseY = ((fract(1.0-coord.s*(width/2.0))*0.75)+(fract(coord.t*(height/2.0))*0.25))*2.0-1.0;
   
    if (noise)
    {
            noiseX = clamp(fract(sin(dot(coord,vec2(12.9898,78.233))) * 43758.5453),0.0,1.0)*2.0-1.0;
            noiseY = clamp(fract(sin(dot(coord,vec2(12.9898,78.233)*2.0)) * 43758.5453),0.0,1.0)*2.0-1.0;
    }
    return vec2(noiseX,noiseY)*2.0;

}

vec3 readColor(in vec2 coord)
{
return texture2D(bgl_RenderedTexture, coord).rgb;
}

float readDepth(in vec2 coord)
{
coord.x = clamp(coord.x,0.001,0.999);
coord.y = clamp(coord.y,0.001,0.999);
return (2.0 * znear) / (zfar + znear - texture2D(bgl_DepthTexture, coord ).x * (zfar-znear));
}

float compareDepths(in float depth1, in float depth2, inout int far)
{
float garea = aowidth; //gauss bell width
float diff = (depth1 - depth2)*100.0; //depth difference (0-100)
//reduce left bell width to avoid self-shadowing
if (diff<gdisplace)
{
garea = diffarea;
}else{
far = 1;
}

    float gauss = pow(2.7182,-2.0*(diff-gdisplace)*(diff-gdisplace)/(garea*garea));
    return gauss;

}

vec3 calAO(float depth,float dw, float dh, inout float ao)
{
vec3 bleed = vec3(0.0,0.0,0.0);
float dd = radius-depth;
float temp = 0.0;
float temp2 = 0.0;
float coordw = gl_TexCoord[0].x + dwdd;
float coordh = gl_TexCoord[0].y + dh
dd;
float coordw2 = gl_TexCoord[0].x - dwdd;
float coordh2 = gl_TexCoord[0].y - dh
dd;

    vec2 coord = vec2(coordw , coordh);
    vec2 coord2 = vec2(coordw2, coordh2);
   
    int far = 0;
    temp = compareDepths(depth, readDepth(coord),far);
    //DEPTH EXTRAPOLATION:
    if (far &gt; 0)
    {
            temp2 = compareDepths(readDepth(coord2),depth,far);
            temp += (1.0-temp)*temp2;
            bleed = readColor(coord);
    }
    ao += temp;
    return temp*bleed;

}

void main(void)
{
vec2 noise = rand(texCoord);
float depth = readDepth(texCoord);

    float fog = doMist();

    vec3 color = texture2D(bgl_RenderedTexture,texCoord).rgb;       
    vec3 lumcoeff = vec3(0.299,0.587,0.114);
    float lum = dot(color.rgb, lumcoeff);
    vec3 luminance = vec3(lum, lum, lum);

    float w = (1.0 / width)/clamp(depth,aoclamp,1.0)*noise.x;
    float h = (1.0 / height)/clamp(depth,aoclamp,1.0)*noise.y;
   
    float pw;
    float ph;
   
    float ao;
    vec3 gi;

    if (optimize)
    {
    samples = float(minsamples)+clamp(1.0-(fog+pow(lum*1.0,4.0)),0.0,1.0)*(float(samples)-float(minsamples));
    }
   
    float dl = PI*(3.0-sqrt(5.0));
    float dz = 1.0/float(samples);
    float l = 0.0;
    float z = 1.0 - dz/2.0;


    for (int i = 0; i &lt;= int(samples); i ++)
    {    
            float r = sqrt(1.0-z);
           
            pw = cos(l)*r*(1.0-doMist());
            ph = sin(l)*r*(1.0-doMist());
            gi += calAO(depth,pw*w,ph*h, ao);        
            z = z - dz;
            l = l + dl;
    }
   
    gi /= samples+0.1;
   
    ao /= samples+0.1;
    ao = 1.0-ao;
   
    if (mist)
    {
    ao = mix(ao, 1.0, fog);
    }
   
    vec3 final = vec3(color*mix(mix(vec3(0.8,0.7,0.5)*0.2,vec3(1.0),vec3(ao)),vec3(1.0),luminance*lumInfluence));//mix(color*ao, white, luminance)
   
    if (onlyAO)
    {
    final = vec3(mix(vec3(ao),vec3(1.0),luminance*lumInfluence)); //ambient occlusion only
    }
   
   
    gl_FragColor = vec4(vec3(final),1.0);

}

Instead of quite tags, you can use code tags, which preserve indentation and make code more readable.

Try replacing this line:


vec3 final = vec3(color*mix(mix(vec3(0.8,0.7,0.5)*0.2,vec3(1.0),vec3(ao)),vec3(1.0),luminance*lumInfluence));

With this:


vec3 final = vec3(color*mix(mix(vec3(0.8,0.7,0.5)*0.2,vec3(1.0),vec3(ao)),vec3(1.0),luminance*lumInfluence*3.0));

Which should make the effect either 3 times stronger or three times weaker. If it’s the wrong way, divide it by 3.0 instead of multiply.

If I’ve misunderstood it, then you could try scaling the vec3(ao)

Thanks, I’ll give it a shot. I’m a pretty lapsed mod, by the way…I should know where the code tags are, but sadly, no.

In terms of understanding this, is the part that makes it 3 times stronger the “vec3” part?

Scratch that. It’s the “influence” bit. That works, and yes, it is /3. Thanks!

What if I wanted to go 5x stronger? 3 works…but just changing the number to 5 doesn’t have an additional effect. Is there another number in that line that has to be changed as well? Thanks.

Indeed, changing the mix factor won’t keep increasing the strength indefinitely. It will increase the strength to a point and then plateau.

At the top of the script there is ‘float radius = 2.0’
Try playing with that (ie increasing it).

Ok, thanks.

Played with that, and I have before I remember. I set it to 5. That’s the spread. I wonder why there’s not simply a strength part?

Heres a version with a strength multiplier


    uniform sampler2D bgl_RenderedTexture;
    uniform sampler2D bgl_DepthTexture;

    uniform float bgl_RenderedTextureWidth;
    uniform float bgl_RenderedTextureHeight;

    #define PI 3.14159265

    float width = bgl_RenderedTextureWidth; //texture width
    float height = bgl_RenderedTextureHeight; //texture height

    vec2 texCoord = gl_TexCoord[0].st;

    float znear = 0.7;
    float zfar = 100.0;

    const float strength = 0.3;

    int samples = 8;

    float radius = 10.0;
    float aoclamp = 0.25;
    float noiseamount = 0.0010;

    float diffarea = 0.3;
    float gdisplace = 0.1;
    float aowidth = 5.0;

    bool onlyAO = false;
    float lumInfluence = 1.0;



    vec2 rand(vec2 coord)
    {
        float noiseX = ((fract(1.0-coord.s*(width/2.0))*0.25)+(fract(coord.t*(height/2.0))*0.75))*2.0-1.0;
        float noiseY = ((fract(1.0-coord.s*(width/2.0))*0.75)+(fract(coord.t*(height/2.0))*0.25))*2.0-1.0;

        return vec2(noiseX,noiseY)*noiseamount;
    }

    float readDepth(in vec2 coord)
    {
        coord.x = clamp(coord.x,0.001,0.999);
        coord.y = clamp(coord.y,0.001,0.999);
        return (2.0 * znear) / (zfar + znear - texture2D(bgl_DepthTexture, coord ).x * (zfar-znear));
    }

    float compareDepths(in float depth1, in float depth2,inout int far)
    {
        float garea = aowidth;
        float diff = (depth1 - depth2)*100.0;
        if (diff&lt;gdisplace)
        {
        garea = diffarea;
        }else{
        far = 1;
        }

        float gauss = pow(2.7182,-2.0*(diff-gdisplace)*(diff-gdisplace)/(garea*garea));
        return gauss;
    }

    float calAO(float depth,float dw, float dh)
    {
        //float dd = (8.0-depth)*radius;
        float dd = radius;
        float temp = 0.0;
        float temp2 = 0.0;
        float coordw = gl_TexCoord[0].x + dw*dd;
        float coordh = gl_TexCoord[0].y + dh*dd;
        float coordw2 = gl_TexCoord[0].x - dw*dd;
        float coordh2 = gl_TexCoord[0].y - dh*dd;

        vec2 coord = vec2(coordw , coordh);
        vec2 coord2 = vec2(coordw2, coordh2);

        int far = 0;
        temp = compareDepths(depth, readDepth(coord),far);
        if (far &gt; 0)
        {
            temp2 = compareDepths(readDepth(coord2),depth,far);
            temp += (1.0-temp)*temp2;
        }

        return temp;
    }

    void main(void)
    {
        vec2 noise = rand(texCoord);
        float depth = readDepth(texCoord);

        float w = (1.0 / width)/clamp(depth,aoclamp,1.0)+(noise.x*(1.0-noise.x));
        float h = (1.0 / height)/clamp(depth,aoclamp,1.0)+(noise.y*(1.0-noise.y));

        float pw;
        float ph;

        float ao;


        float dl = PI*(3.0-sqrt(5.0));
        float dz = 1.0/float(samples);
        float l = 0.0;
        float z = 1.0 - dz/2.0;

        for (int i = 0; i &lt;= samples; i ++)
        {
            float r = sqrt(1.0-z);

            pw = cos(l)*r;
            ph = sin(l)*r;
            ao += calAO(depth,pw*w,ph*h);
            z = z - dz;
            l = l + dl;
        }

        ao /= float(samples);
        ao = 1.0-ao*strength;

        vec3 color = texture2D(bgl_RenderedTexture,texCoord).rgb;

        vec3 lumcoeff = vec3(0.299,0.587,0.114);
        float lum = dot(color.rgb, lumcoeff);
        vec3 luminance = vec3(lum, lum, lum);

        vec3 final = mix(vec3(ao),vec3(1.0),luminance);

        if (onlyAO)
        {
        final = vec3(mix(vec3(ao),vec3(1.0),luminance*lumInfluence));
        }

        vec3 result = final*color;

        gl_FragColor.rgba = vec4(result,1.0);
    }



That’s the one. 20 minutes of tinkering with that and I’ve got a good, deep ao. Bear in mind I’m making castle sets to sell, so this isn’t for a sunny meadow. I need dark corners and an old feel. Thanks all.

Attachments