Problem, alpha is always equal to one.

Hi! For my new OIT rendering technique I need to compute the alpha value in a separate texture.
When I compute colors it’s good :


const std::string addSrcColorFragShader =
                "#version 130 
"
                "in mat4 projMat;"
                "uniform vec3 resolution;"
                "uniform sampler2D frontBuffer;"
                "uniform sampler2D depthBuffer;"
                "uniform sampler2D stencilBuffer;"
                "uniform sampler2D texture;"
                "uniform float haveTexture;"
                "void main() {"
                    "vec2 position = (gl_FragCoord.xy / resolution.xy);"
                    "vec4 front_color = texture2D(frontBuffer, position);"
                    "float max_z = texture2D(depthBuffer, position).z;"
                    "float nbLayers = texture2D (stencilBuffer, position).a;"
                    "vec4 texel = texture2D(texture, gl_TexCoord[0].xy);"
                    "float z = (gl_FragCoord.w != 1.f) ? (inverse(projMat) * vec4(0, 0, 0, gl_FragCoord.w)).w : gl_FragCoord.z;"
                    "vec4 colors[2];"
                    "colors[1] = texel * gl_Color;"
                    "colors[0] = gl_Color;"
                    "bool b = (haveTexture > 0.9);"
                    "vec4 color = colors[int(b)];"
                    "colors[1] = vec4(color.rgb * (1 - front_color.a), 1);"
                    "colors[0] = vec4(0, 0, 0, 0);"
                    "b = (z < max_z);"
                    "gl_FragColor = colors[int(b)];"
                "}";
                const std::string addDstColorFragShader =
                "#version 130 
"
                "in mat4 projMat;"
                "uniform vec3 resolution;"
                "uniform sampler2D frontBuffer;"
                "uniform sampler2D depthBuffer;"
                "uniform sampler2D stencilBuffer;"
                "uniform sampler2D texture;"
                "uniform float haveTexture;"
                "void main() {"
                    "vec2 position = (gl_FragCoord.xy / resolution.xy);"
                    "vec4 front_color = texture2D(frontBuffer, position);"
                    "float max_z = texture2D(depthBuffer, position).z;"
                    "float nbLayers = texture2D(stencilBuffer, position).a;"
                    "vec4 texel = texture2D(texture, gl_TexCoord[0].xy);"
                    "float z = (gl_FragCoord.w != 1.f) ? (inverse(projMat) * vec4(0, 0, 0, gl_FragCoord.w)).w : gl_FragCoord.z;"
                    "vec4 colors[2];"
                    "colors[1] = texel * gl_Color;"
                    "colors[0] = gl_Color;"
                    "bool b = (haveTexture > 0.9);"
                    "vec4 color = colors[int(b)];"
                    "colors[1] = vec4(front_color.rgb * front_color.a, 1);"
                    "colors[0] = vec4(0, 0, 0, 0);"
                    "b = (z < max_z || (z >= max_z && nbLayers <=1));"
                    "gl_FragColor = colors[int(b)];"
                "}";
                const std::string avgFragShader =
                "#version 130 
"
                "in mat4 projMat;"
                "uniform sampler2D texture;"
                "uniform sampler2D stencilBuffer;"
                "uniform vec2 resolution;"
                "void main() {"
                    "vec2 position = (gl_FragCoord.xy / resolution.xy);"
                    "vec4 color = texture2D(texture, gl_TexCoord[0].xy);"
                    "float nbLayers = texture2D(stencilBuffer, position).a;"
                    "vec4 colors[2];"
                    "colors[0] = vec4(0, 0, 0, 0);"
                    "colors[1] = vec4(color.r / nbLayers, color.g / nbLayers, color.b / nbLayers, 1);"
                    "bool b = (nbLayers > 0);"
                    "gl_FragColor = colors[int(b)];"
                "}";

But when I want to compute the alpha here to add the correct alpha value to the final texture the values here are always equal to one.


const std::string setAlphaFragShader =
                "#version 130 
"
                "uniform vec3 resolution;"
                "uniform sampler2D texture;"
                "uniform sampler2D frameBuffer;"
                "void main() {"
                    "vec2 position = (gl_FragCoord.xy / resolution.xy);"
                    "float alpha = texture2D(texture, gl_TexCoord[0].xy).a;"
                    "vec4 color = texture2D(frameBuffer, position);"
                    "gl_FragColor = vec4(color.rgb * alpha, alpha);"
                "}";

I draw every nearest sprites first because I need to blend every sprites with the nearest, in one shader I perform addition of all SRCCOLCOR * (ONE_MINUS_SRC_COLOR) with a dethtest to don’t blend the sprite with itselfs. (So I use additive blending)
In another shader, I add every DSTCOLOR * DSTALPHA I do a dethtest to don’t blend the sprite with itselfs but I need to draw it if it’s the single fragment at this position.
In another shader a compute the average color of the sum of SRCCOLCOR * (ONE_MINUS_SRC_COLOR) and I compute the average of the sum of DSTCOLOR * DSTALPHA and then I add the two averaged values with additive blending.
(Ok colours are correct when I dispaly the final texture)
I set alpha to 1 because if I do the average of DSTALPHA and SRCALPHA * ONEMINUSDSTALPHA, it doesn’t get me the correct final alpha. So I need to compute it in a separate texture.

I draw the scene here :

[code=cpp]
for (unsigned int i = 0; i < m_instances.size(); i++) {
if (m_instances[i].getMaterial().getTexture() == nullptr)
depthBufferGenerator.setParameter(“haveTexture”, 0);
else
depthBufferGenerator.setParameter(“haveTexture”, 1);
currentStates.shader=&depthBufferGenerator;
currentStates.texture=m_instances[i].getMaterial().getTexture();
depthBuffer.draw(m_instances[i].getAllVertices(),currentStates);
currentStates.shader = nullptr;
currentStates.blendMode = BlendNone;
frontBuffer.draw(m_instances[i].getAllVertices(), currentStates);
stencilBuffer.draw(m_instances[i].getAllVertices(),currentStates);
}
frontBuffer.display();
frontBufferSprite.setCenter(view.getPosition());



And later ...

[code=cpp]
currentStates.blendMode = sf::BlendMode(sf::BlendMode::Factor::Zero, sf::BlendMode::Factor::Zero, sf::BlendMode::Equation::Add, sf::BlendMode::Factor::One, sf::BlendMode::Factor::Zero, sf::BlendMode::Equation::Add);
            alpha.draw(frontBufferSprite, currentStates);
            currentStates.blendMode = sf::BlendMode(sf::BlendMode::Factor::Zero,sf::BlendMode::Factor::Zero,sf::BlendMode::Equation::Add,sf::BlendMode::Factor::OneMinusDstAlpha, sf::BlendMode::Factor::One, sf::BlendMode::Equation::Add);
            currentStates.shader=&frameBufferGenerator;
            for (unsigned int i = 0; i < m_instances.size(); i++) {
                if (m_instances[i].getMaterial().getTexture() == nullptr)
                    frameBufferGenerator.setParameter("haveTexture", 0);
                else
                    frameBufferGenerator.setParameter("haveTexture", 1);
                currentStates.texture = m_instances[i].getMaterial().getTexture();
                alpha.draw(m_instances[i].getAllVertices(), currentStates);
            }
            alpha.display();
            alphaSprite.setCenter(view.getPosition());

The problem : when I compute the final color here :


 const std::string setAlphaFragShader =
                "#version 130 
"
                "uniform vec3 resolution;"
                "uniform sampler2D texture;"
                "uniform sampler2D frameBuffer;"
                "void main() {"
                    "vec2 position = (gl_FragCoord.xy / resolution.xy);"
                    "float alpha = texture2D(texture, gl_TexCoord[0].xy).a;"
                    "vec4 color = texture2D(frameBuffer, position);"
                    "gl_FragColor = vec4(color.rgb * alpha, alpha);"
                "}";

If I display only alpha values here, it’s an all white texture so all alpha values are set to one. (even if my sprite are transparent)

Why ? Isn’t the blending supposed to write the correct alpha value in the rendertexture ? (if I use glOne * SrcAlpha for my blending equation)

This is what it does when I use sf::BlendNone.

Hmmm…it seems it doesn’t write the alpha value of my FBO I used a shader instead.