View Single Post
  #1  
Old 10-07-2011, 11:22 AM
FranciscoPeters FranciscoPeters is offline
Member
 
Join Date: Oct 2011
Posts: 2
Cool SSAO Shader Implementation

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:
Code:
/*******************************************************************************/
/*
 * 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:
Code:
/*******************************************************************************/
/*
 * 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:
Code:
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.
Reply With Quote