Hello everyone, I’ve been trying to implement the SSAO shader for several days without success. Maybe someone can help me.
I am using this fragment shader:
uniform sampler2D texture0;
uniform sampler2D texture1;
uniform vec2 camerarange;
uniform vec2 screensize;
float readDepth( in vec2 coord ) {
return (2.0 * camerarange.x) / (camerarange.y + camerarange.x - texture2D( texture0, coord ).x * (camerarange.y - camerarange.x));
}
void main(void)
{
vec2 texCoord = gl_TexCoord[0].st;
//vec2 texCoord = texture2D(texture0, gl_TexCoord[0].st).xy;
//vec3 texColor = texture2D(texture1, gl_TexCoord[0].st).rgb;
float depth = readDepth( texCoord );
float d;
float pw = 1.0 / screensize.x;
float ph = 1.0 / screensize.y;
float aoCap = 0.45;
float ao = 0.0;
float aoMultiplier=1000.0;
float depthTolerance = 0.00001;
d=readDepth( vec2(texCoord.x+pw,texCoord.y+ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
d=readDepth( vec2(texCoord.x-pw,texCoord.y+ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
d=readDepth( vec2(texCoord.x+pw,texCoord.y-ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
d=readDepth( vec2(texCoord.x-pw,texCoord.y-ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
pw*=2.0;
ph*=2.0;
aoMultiplier/=2.0;
d=readDepth( vec2(texCoord.x+pw,texCoord.y+ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
d=readDepth( vec2(texCoord.x-pw,texCoord.y+ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
d=readDepth( vec2(texCoord.x+pw,texCoord.y-ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
d=readDepth( vec2(texCoord.x-pw,texCoord.y-ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
pw*=2.0;
ph*=2.0;
aoMultiplier/=2.0;
d=readDepth( vec2(texCoord.x+pw,texCoord.y+ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
d=readDepth( vec2(texCoord.x-pw,texCoord.y+ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
d=readDepth( vec2(texCoord.x+pw,texCoord.y-ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
d=readDepth( vec2(texCoord.x-pw,texCoord.y-ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
pw*=2.0;
ph*=2.0;
aoMultiplier/=2.0;
d=readDepth( vec2(texCoord.x+pw,texCoord.y+ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
d=readDepth( vec2(texCoord.x-pw,texCoord.y+ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
d=readDepth( vec2(texCoord.x+pw,texCoord.y-ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
d=readDepth( vec2(texCoord.x-pw,texCoord.y-ph));
ao+=min(aoCap,max(0.0,depth-d-depthTolerance) * aoMultiplier);
ao/=16.0;
gl_FragColor = vec4(1.2-ao) * texture2D(texture1, texCoord);
}
And this vertex :
#version 110
void main(){
gl_Position = ftransform();
gl_TexCoord[0] = gl_MultiTexCoord0;
}
RENDER:
First I get the depthmap and scene textures from a framebuffer. And this is the result
fbo.begin();
Gdx.gl.glClearColor(0.1f, 0.1f, 0.1f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
modelBatch.begin(cam);
modelBatch.render(models);
modelBatch.end();
fbo.end();
Texture diffuseText = fbo.getTextureAttachments().get(DIFFUSE_ATTACHMENT);
Texture depthText = fbo.getTextureAttachments().get(DEPTH_ATTACHMENT);
diffuse : https://i.imgur.com/fj2oPmT.png
depthMap: https://i.imgur.com/1Q9Zf3n.png
Next step, I apply the ssao shader and render it in a full screen quad
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
depthText .bind(0);
diffuseText .bind(1);
shaderProgramSSAO.begin();
shaderProgramSSAO.setUniformi("texture0", 0);
shaderProgramSSAO.setUniformi("texture1", 1);
shaderProgramSSAO.setUniformf("camerarange", new Vector2(cam.near, cam.far)); // near=1, far=20
shaderProgramSSAO.setUniformf("screensize", new Vector2(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()));
mesh.render(shaderProgramSSAO, GL20.GL_TRIANGLES);
shaderProgramSSAO.end();
But the only result I get is a black screen.
Any suggestions? What am I doing wrong?
Thanks in advance