PDA

View Full Version : SSAO Shader Implementation


FranciscoPeters
10-07-2011, 11:22 AM
First of all I'd like to thank everyone for the information that has been posted on this forum, it has really helped me a lot in getting to know Vizard.

Currently, I'm using Vizard 3.0 (evaluation version) to build a realistic environment and I'm trying to implement some advanced shaders that are quite standard in other 3D engines. Please note that I'm not a programmer by nature (I'm a 3D artist), so I do realize I've been really spoiled with all the visual editors in other 3D engines (like UDK) to achieve my goals visually.

In short: I've been trying to implement a SSAO (screen space ambient occlusion) shader I found on the web, but cannot seem to get it to work. It's not giving me any errors (in Vizard anyway).

I'm not asking for a straight answer, because I'm sure there isn't one, but if anyone can point me into the right direction I would be a very happy man :)

Here is the fragment shader I'm trying to implement:
/************************************************** *****************************/
/*
* Author: Ing. Jose Larios Delgado.
* Project: glsl shaders implementation with OpenSceneGraph.
* Institutions: DGSCA, UNAM, Virtual Reality Department.
* Description: SSAO.
* Distributed under the terms of the GNU Lesser General Public License (LGPL)
*/
/************************************************** *****************************/

uniform sampler2D texture0;
uniform sampler2D texture1;

uniform vec2 camerarange;
uniform vec2 screensize;

uniform bool flag;

varying vec2 texCoord;


float readDepth( in vec2 coord ) {
return (2.0 * camerarange.x) / (camerarange.y + camerarange.x - texture2D( texture0, coord ).x * (camerarange.y - camerarange.x));
}

float compareDepths( in float depth1, in float depth2 ) {
float aoCap = 1.0;
float aoMultiplier=10000.0;
float depthTolerance=0.000;
float aorange = 10.0;// units in space the AO effect extends to (this gets divided by the camera far range
float diff = sqrt( clamp(1.0-(depth1-depth2) / (aorange/(camerarange.y-camerarange.x)),0.0,1.0) );
float ao = min(aoCap,max(0.0,depth1-depth2-depthTolerance) * aoMultiplier) * diff;
return ao;
}

void main(void)
{
float depth = readDepth( texCoord );
float d;

float pw = 1.0 / screensize.x;
float ph = 1.0 / screensize.y;

float aoCap = 1.0;

float ao = 0.0;

float aoMultiplier=10000.0;

float depthTolerance = 0.001;

float aoscale=1.0;

d=readDepth( vec2(texCoord.x+pw,texCoord.y+ph));
ao+=compareDepths(depth,d)/aoscale;

d=readDepth( vec2(texCoord.x-pw,texCoord.y+ph));
ao+=compareDepths(depth,d)/aoscale;

d=readDepth( vec2(texCoord.x+pw,texCoord.y-ph));
ao+=compareDepths(depth,d)/aoscale;

d=readDepth( vec2(texCoord.x-pw,texCoord.y-ph));
ao+=compareDepths(depth,d)/aoscale;

pw*=2.0;
ph*=2.0;
aoMultiplier/=2.0;
aoscale*=1.2;

d=readDepth( vec2(texCoord.x+pw,texCoord.y+ph));
ao+=compareDepths(depth,d)/aoscale;

d=readDepth( vec2(texCoord.x-pw,texCoord.y+ph));
ao+=compareDepths(depth,d)/aoscale;

d=readDepth( vec2(texCoord.x+pw,texCoord.y-ph));
ao+=compareDepths(depth,d)/aoscale;

d=readDepth( vec2(texCoord.x-pw,texCoord.y-ph));
ao+=compareDepths(depth,d)/aoscale;

pw*=2.0;
ph*=2.0;
aoMultiplier/=2.0;
aoscale*=1.2;

d=readDepth( vec2(texCoord.x+pw,texCoord.y+ph));
ao+=compareDepths(depth,d)/aoscale;

d=readDepth( vec2(texCoord.x-pw,texCoord.y+ph));
ao+=compareDepths(depth,d)/aoscale;

d=readDepth( vec2(texCoord.x+pw,texCoord.y-ph));
ao+=compareDepths(depth,d)/aoscale;

d=readDepth( vec2(texCoord.x-pw,texCoord.y-ph));
ao+=compareDepths(depth,d)/aoscale;

pw*=2.0;
ph*=2.0;
aoMultiplier/=2.0;
aoscale*=1.2;

d=readDepth( vec2(texCoord.x+pw,texCoord.y+ph));
ao+=compareDepths(depth,d)/aoscale;

d=readDepth( vec2(texCoord.x-pw,texCoord.y+ph));
ao+=compareDepths(depth,d)/aoscale;

d=readDepth( vec2(texCoord.x+pw,texCoord.y-ph));
ao+=compareDepths(depth,d)/aoscale;

d=readDepth( vec2(texCoord.x-pw,texCoord.y-ph));
ao+=compareDepths(depth,d)/aoscale;

ao/=16.0;

//gl_FragColor = vec4(1.0-ao) * texture2D(texture1,texCoord);
//gl_FragColor = vec4(1.0-ao);


if(flag)
//gl_FragColor = vec4(1.0-ao);
gl_FragColor = vec4(1.1-ao) * texture2D(texture1,texCoord);
else
gl_FragColor = texture2D(texture1,texCoord);
}

And the vertex shader:
/************************************************** *****************************/
/*
* Author: Ing. Jose Larios Delgado.
* Project: glsl shaders implementation with OpenSceneGraph.
* Institutions: DGSCA, UNAM, Virtual Reality Department.
* Description: SSAO.
* Distributed under the terms of the GNU Lesser General Public License (LGPL)
*/
/************************************************** *****************************/

varying vec2 texCoord;

void main(void) {
//gl_Position = ftransform();
//texCoord=gl_MultiTexCoord0.xy;
//gl_FrontColor = gl_Color;


vec2 Pos = sign(gl_Vertex.xy);

gl_Position = vec4(Pos.xy, 0.0, 1.0);
texCoord = Pos * 0.5 + 0.5;
//gl_FrontColor = gl_Color;
}

And this is my python script for Vizard:
import viz

viz.go()
viz.clearcolor(0.5, 0.5, 1.0)
object = viz.add('cubus.IVE')

object.color(viz.WHITE)
object.texture(viz.add('diffuse.tga'),unit=0)
object.texture(viz.add('diffuse.tga'),unit=1)

shader = viz.addShader(vert='ssaovert.vert',frag='ssaofrag. frag')
object.apply(shader)
object.apply(viz.addUniformInt('texture0',0))
object.apply(viz.addUniformInt('texture1',1))
object.apply(viz.addUniformBool('flag',0))

As you might notice, the boolean flag is to turn SSAO on/off, as it was originally intended by the author. Am I going at it totally wrong here? Any help is really appreciated.

I'll gladly put this online (if it works) and share it with everyone of course, since there aren't many easy to implement shaders for artists like me out there who use Vizard and there seems to be some demand on this forum.

Jeff
10-07-2011, 05:36 PM
Attached is an example using an SSAO shader you can use.

FranciscoPeters
10-08-2011, 04:19 AM
Thanks a million Jeff! I took a look at the example and first of all, it works perfectly! The code looks practically the same, although here and there some GLSL uniforms have been changed to Vizard uniforms. I only found a couple of Vizard uniforms here (http://docs.worldviz.com/vizard/Shaders_basics.htm), but I'm guessing there are a quite some more?

Anyway, a big thanks :) Going to move on to my water shader and HDR implementation. This will surely help my scene get that extra pop! Thanks again.