Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 5 of 5

Thread: [GLSL 130] Why I don't have the excepted final color in my shader ?

  1. #1
    Intern Newbie
    Join Date
    Jul 2014
    Posts
    46

    [GLSL 130] Why I don't have the excepted final color in my shader ?

    Hi everyone!

    My plateform (Ubuntu 14.4 LTS 64 bits) only support opengl 3.0 and GLSL 130, I can't use pixel linked list from opengl 450.

    I'm trying to find an alternative so :

    Here is the technique which I use :

    I clear an FBO with a clear color, at each time I draw something, I get the texture. I also use an FBO with transparent color, and I get a second texture. (for the depthbuffer)

    In the first texture I save the color of each fragment and in the second texture I save the depth and the alpha of each fragment. (You'll see why further)

    The first object is drawn with the classical blending equation so :

    Blending : clear color (0, 0, 0, 1)

    FB color : (0, 0, 0, 1)
    DB z : 0
    a : 0
    Current Color : (1, 0, 0, 0.5)
    Current z : 0
    a = 0.5

    Final color = (1, 0, 0, 0.5) * 0.5 + (0, 0, 0, 1) * (1 - 0.5) = (0.5, 0, 0, 0.75)

    FB color is the color written in the first texture, DB z and a are the depth and the alpha written in the second texture, Current Color and Current z and a are the color, the z and the alpha of what I'm curretly drawing.

    So the equation is SRCCOLOR * SRCALPHA + DSTCOLOR * (1 - SRCALPHA)

    I need to change the blending equation, if the object I draw is behind the object which is already drawn, so in this case the bleding equation is

    DSTCOLOR * DSTALPHA + SRCCOLOR * (1 - DSTALPHA)

    So dstalpha is the alpha of the fragment which has been drawn previously, I give the same color in the two cases so it doesn't matter is an object is behind or before another one, in other worlds, the order in which I draw my objects doesn't matter.

    Case 1 : (The object which is drawn is behind the object to draw.)

    FB color : (1, 0, 0, 0.75)
    DB z : 0
    DB a : 0.5
    Current Color : (1, 1, 0, 0.5)
    Current z : 1
    a : 0.5

    Final color : (1, 1, 0, 0.5) * 0.5 + (1, 0, 0, 0.75) * (1 - 0.5) = (1, 0.5, 0, 0.652)

    ---------------------------------------------------------------------------

    Cas 2 : (The object which is drawn is before the object I draw.)

    FB color : (1, 0, 0, 0.75)
    DB z : 1
    DB a : 0.5
    Current Color : (1, 1, 0, 0.5)
    Current z : 0
    a : 0.5

    Final color : (1, 1, 0, 0.5) * 0.5 + (1, 0, 0, 0.75) * (1 - 0.5) = (1,0.5, 0, 0, 625)

    So I desactivated the opengl blending and I've written this two shader (he one to generate the first texture, and the second to generate the second and the final texture that I draw on the window)

    The vertex shader is very simple and is the same for both textures.

    Code :
    #version 130
    out mat4 projMat;
    void main () {
           gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
           gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
           gl_FrontColor = gl_Color;
           projMat = gl_ProjectionMatrix;
    };

    The fragment shader for the first texture is :

    Code :
    #version 130 \n
    uniform sampler2D depthBuffer;
    uniform sampler2D texture;
    uniform vec3 resolution;"
    uniform float haveTexture;
    in mat4 projMat;
    void main () {
           vec2 position = ( gl_FragCoord.xy / resolution.xy );
           vec4 color = texture2D(depthBuffer, position);
           vec4 pixel = (haveTexture==1) ? gl_Color * texture2D(texture, gl_TexCoord[0].xy) : gl_Color;
           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] = vec4(z, pixel.a, z, pixel.a);
           colors[0] = vec4(z, pixel.a, color.b, color.a);
           bool b = (z >= color.z && pixel.a >= color.a);
           gl_FragColor = colors[int(b)];
    }

    And the one for the second texture is :

    Code :
    #version 130 \n
    uniform sampler2D depthBuffer;
    uniform sampler2D frameBuffer;
    uniform sampler2D texture;
    uniform vec3 resolution;
    uniform float haveTexture;
    in mat4 projMat;
    void main () {
           vec2 position = ( gl_FragCoord.xy / resolution.xy );
           vec4 depth = texture2D(depthBuffer, position);
           vec4 color = texture2D(frameBuffer, position);
           vec4 pixel = (haveTexture==1) ? gl_Color * texture2D(texture, gl_TexCoord[0].xy) : gl_Color;
           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] = pixel * pixel.a + color * (1 - pixel.a);       
           colors[0] = color * depth.g + pixel * (1 - depth.g);      
           bool b = (z >= depth.r);
           gl_FragColor = colors[int(b)];

    I avoid to use an if structure for optimization purposes.

    My code simply draw two rectangles (a semi-transparent red one and a semi-transparent yellow one) on the textures with the shaders.

    Code :
    currentStates.shader = frameBufferGenerator;
    frameBuffer->draw(m_instances[i]->getVertexArray(), currentStates);
    frameBuffer->display();
    currentStates.shader = depthBufferGenerator;
    depthBuffer->draw(m_instances[i]->getVertexArray(), currentStates);
    depthBuffer->display();

    But the result I get is not the result that I expected.

    The alpha blending is not performed. :/

    Here is what I have :

    Click image for larger version. 

Name:	Capture du 2015-03-09 14:29:23.jpg 
Views:	184 
Size:	14.4 KB 
ID:	1664

    Why the blending isn't applied in my fragment shader ?

    Thanks for help.
    Last edited by Lolilolight; 03-09-2015 at 06:40 AM.

  2. #2
    Intern Newbie
    Join Date
    Jul 2014
    Posts
    46
    Erf I've found why, this is because, I draw every vertices of each quads at once for optimization purpose, so I need to find another solution, if anyone have an idea.

  3. #3
    Intern Newbie
    Join Date
    Jul 2014
    Posts
    46
    Now I draw the rectangles one by one and it works, but the number of draw call increase so the FPS decrease and I've a FPS between 15-20 instead of an FPS between 25-30.

    The only solution that I've is to read/write fragments at the same time, so, I don't have to wait that the rectangle is drawn to get fragments colors and depth in the buffer but I don't thing this is possible. :/

  4. #4
    Senior Member OpenGL Guru
    Join Date
    Jun 2013
    Posts
    2,953
    Quote Originally Posted by Lolilolight View Post
    The only solution that I've is to read/write fragments at the same time, so, I don't have to wait that the rectangle is drawn to get fragments colors and depth in the buffer but I don't thing this is possible.
    Not with OpenGL 3.x. You can do it with image load/store, but that requires OpenGL 4.2.

  5. #5
    Intern Newbie
    Join Date
    Jul 2014
    Posts
    46
    Arf..., ok, so I haven't any choise, I have to draw the faces of my object one by one.

    It's slower but at least it works with order independant transparency.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •