NeomerArcana
NeomerArcana

Reputation: 2279

OpenGL Frag Shader texture fades after every write

I have a program that takes the following texture:

enter image description here

which is generated via FreeType2. Basically, it's creating a texture atlas for every character that I've requested to be drawn. As you can see, the characters are bright and clear. In fact, you can see that the top-leftmost pixel of the lowercase 'i' has a value of 71 (out of 255) or 0.7098 when I inspect the texture in RenderDoc.

Next, the engine blits letters onto a Framebuffer Object. This is done via textured quads. The vertex shader:

#version 330

layout(location=0) in vec2 inVertexPosition;
layout(location=1) in vec2 inTexelCoords;
layout(location=2) in float inDepth;

out vec2 texelCoords;
out float depth;

void main()
{
    gl_Position = vec4(inVertexPosition.x,-inVertexPosition.y, 0.0, 1.0);
    texelCoords = vec2(inTexelCoords.x,1-inTexelCoords.y);
    depth = inDepth;
}

And the frag shader:

#version 330

layout(location=0) out vec4 frag_colour;

in vec2 texelCoords;
in float depth;

uniform sampler2D uTexture;
uniform vec4 uTextColor;

void main()
{
    vec4 c = texture(uTexture,texelCoords);
    frag_colour = uTextColor * c.r;
    gl_FragDepth = depth;
}

As you can see, it's sets the pixel color to be a factor of the red channel.

However, when I view the contents of the FBO via RenderDoc, and saved out to file here, you see this:

enter image description here

If you look at this without transparency (just a second layer added underneath in Gimp to illustrate better):

enter image description here

You can see that the text is a little faded compared to what it was before. If you look at the top-leftmost pixel of the lowercase 'i', it's now a value of 50.2, or for a range of 0-1 it's 0.50196 (via RenderDoc).

Next, when the FBO is finally put onto the screen via another textured quad it fades even more. First here's the vertex shader:

#version 330

layout(location=0) in vec2 inVertexPosition;
layout(location=1) in vec2 inTexelCoords;

varying vec2 texelCoords;

void main()
{
    gl_Position = vec4(inVertexPosition.x,-inVertexPosition.y, 0.0, 1.0);
    texelCoords = vec2(inTexelCoords.x,1-inTexelCoords.y);
}

and the fragment shader:

#version 330

precision highp float;

layout(location=0) out vec4 frag_colour;

varying vec2 texelCoords;

uniform sampler2D uTexture;

void main()
{
    vec4 c = texture(uTexture,texelCoords);
    frag_colour = c;
}

The results, as I said are more faded than before:

original: enter image description here

gimp background for clarity:

enter image description here

now that pixel has a value of 25.1 or 0.05139.

What is causing this fading after every render?

I think it's important to note that the brighter areas don't fade.

My Framebuffer creation code

glGenFramebuffers(1, &m_framebuffer);
glGenTextures(1, &m_fboColorAttachment);
glGenTextures(1, &m_fboAdditionalInfo);
glGenTextures(1, &m_fboDepthStencil);

glCall(glBindFramebuffer,GL_FRAMEBUFFER, m_framebuffer);

    /* setup color output 0 */
    glBindTexture(GL_TEXTURE_2D, m_fboColorAttachment);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
        glCall(glTexImage2D, GL_TEXTURE_2D, 0, GL_RGBA8, screenDimensionsX, screenDimensionsY, 0, GL_BGRA, GL_UNSIGNED_BYTE, nullptr);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_fboColorAttachment, 0);
    glBindTexture(GL_TEXTURE_2D, 0);

    /* setup color output 1 */
    glBindTexture(GL_TEXTURE_2D, m_fboAdditionalInfo);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
        glCall(glTexImage2D, GL_TEXTURE_2D, 0, GL_R32UI, screenDimensionsX, screenDimensionsY, 0, GL_RED_INTEGER, GL_UNSIGNED_INT, nullptr);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, GL_TEXTURE_2D, m_fboAdditionalInfo, 0);
    glBindTexture(GL_TEXTURE_2D, 0);

    /* setup depth and stencil */
    glBindTexture(GL_TEXTURE_2D, m_fboDepthStencil);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP_TO_EDGE);
        glCall(glTexImage2D, GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, screenDimensionsX, screenDimensionsY, 0, GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_fboDepthStencil, 0);
    glBindTexture(GL_TEXTURE_2D, 0);

The initial (red) texture creation:

glActiveTexture(GL_TEXTURE0);
glGenTextures(1,&textureData.texture);
glBindTexture(GL_TEXTURE_2D,textureData.texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, 500, 500, 0, GL_RED, GL_UNSIGNED_BYTE, 0);
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

My blending is done as

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

Upvotes: 0

Views: 146

Answers (1)

derhass
derhass

Reputation: 45332

has a value of 71 (out of 255) or 0.7098

No idea, what you even mean here. 71/255 would be 0.278. 0.7098 normalized would be 181 out of 255. Looks like your "out of 255" are just percentage values, out of 100%.

glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

You use that color values from the red channel also as alpha, so, when you have blending enabled, you end up with 0.7098*0.7098=.5038. Since the result will be rounded to the nearest reprersentable value, we rather end with 181/255 * 181/255 = .50382 rounded to 128/255

it's now a value of 50.2, or for a range of 0-1 it's 0.50196

128/255 is 0.50196078....

So the solution is: disable blending for all steps when you don't need it. Or if you need it, set useful alpha values.

Side note:

now that pixel has a value of 25.1 or 0.05139.

No Idea what this means, the 25.1 does not relate to 0.05139 in any obvious way, you definitively switched the meaning of those values again.

Upvotes: 1

Related Questions