[SOLVED] SSAO buffer texture wrong

Hi guys.

I need some help regarding to SSAO. I’ve followed this popular tutorial: https://learnopengl.com/Advanced-Lighting/SSAO.
Somehow, the occlusion factor is always 1, so no changes can be observed.

I debugged through the code and:

  • The GBuffer textures are correct
  • The problem is might be the SSAO texture itself.

So… when I generate the ssao texture onto the screen, it’s totally red and if I change the ssao shader output value to any float, it remains red. That’s why I think, the problem is somewhere over there.

The code is the same as in the tutorial, but here it is the ssao buffer:


FBO = glGenFramebuffers();
blurFBO = glGenFramebuffers();

glBindFramebuffer(GL_FRAMEBUFFER, FBO);

LOGGER.debug("> Creating color texture...");
int ssaoColorTexture = glGenTextures();
glBindTexture(GL_TEXTURE_2D, ssaoColorTexture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, Engine.properties.getWindowWidth(), Engine.properties.getWindowHeight(), 0, GL_RGB, GL_FLOAT, (ByteBuffer) null);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, ssaoColorTexture, 0);

if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) {
     throw new RuntimeException("SSAO buffer is not completed");
}

In the fragment shader I just use

layout (location = 0) out float OUT_Color;

And assign it:

OUT_Color =1.0f

And the value above does not affect the texture in the FBO.

What can be the problem, where should I continue debugging?

Well, you’ve assigned your texture to:

glTexImage2D(GL_TEXTURE_2D, 0, GL_RED...)

So, it only has the red channel of color.


But if I understand correctly… even if you output something like:

OUT_Color = 0.0f;

It is still red?


Are you drawing a fullscreen quad on your screen with that shader bound? Otherwise nothing will change, because there’s nothing being sent to the fragment shader.

Also… a lot of this code looks like it was lazily taken from John Chapman’s blog

I do the exact same stuff that is on the page I linked. After the SSAO texture is generated, I pass it to the last shader where it affects the final color. As I saw it has no effect on the fragment’s color, I started to debug if something is wrong with the SSAO texture.

First, I checked the GBuffer textures, all are good. Second, I checked the SSAO texture if its wrong and it is. No matter what I set to the OUT_Color, the texture will be completely red.

I tried what if I expect RGBA and output a vec4 from the shader with a fixed value. In that case, the texture turned to white and no matter what I set for the OUT_Color, it remains white. Now I think the problem is around the framebuffer code, but went 10 times through it and looks good. Maybe I have to sleep and retry tomorrow :slight_smile:

BTW, when I write I checked the texture I mean I draw it onto the upper right using nanovg.

Here is the render logic:


    public void onRender() {
        GL11.glClearColor(1f, 1f, 1f, 1f);
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_STENCIL_BUFFER_BIT);

        batches.values().forEach(RenderBatch::initGPUDataStores); // it sets up VAO, VBO, etc

        computeSSAOGeometryData(() -> {
            ssaoGeometryShader.bind();
            batches.values().forEach(renderBatch -> {
                // TODO: what if it does not have texture?
                ssaoGeometryShader.updateMaterialDiffuseTexture(renderBatch);
                renderBatch.render();
            });
            ssaoGeometryShader.unbind();
        });

        computeSSAOTexture(() -> {
            ssaoShader.bind();
            batches.values().forEach(renderBatch -> {
                renderBatch.render();
            });
            ssaoShader.unbind();
        });

        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);
        batches.values().forEach(renderBatch -> {
            renderBatch.getMaterial().getShader().bind();

            ((StandardShader)renderBatch.getMaterial().getShader()).ssao(ssaoBuffer);

            renderBatch.render();
            renderBatch.getMaterial().getShader().unbind();
        });
    }

    private void computeSSAOGeometryData(Runnable batchRendering) {
        GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, gBuffer.getGFBO());
        GL11.glClear(GL11.GL_DEPTH_BUFFER_BIT | GL11.GL_COLOR_BUFFER_BIT);

        batchRendering.run();

        GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
    }

    private void computeSSAOTexture(Runnable batchRendering) {
        GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, ssaoBuffer.getFBO());
        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

        batchRendering.run();

        GL30.glBindFramebuffer(GL30.GL_FRAMEBUFFER, 0);
    }

And forgot to mention that the code was taken (ported to java) from learnopengl.com where the guy clearly wrote down that he used John Chapman’s as a source.

I think, I found some issues, so I collect all of them here for the future generation.

  • Don’t forget to disable GL_BLEND during the geometry pass
  • The texture was completely red, because something went wrong in the SSAO shader and the I used white in the glClearColor which was a basic completly white base, so the whole turned into red
  • Some of the GPUs’ drivers don’t support GL_RGB16F, you have to use GL_RGBA16F or GL_RGBA32F in the GBuffer for normals and positions

The SSAO texture is still not OK, I’ll write back when I find the problem.

SSAO texture is now OK, there were one more typo :slight_smile: