Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 12

Thread: Translucency and multi-pass lighting

  1. #1
    Junior Member Newbie
    Join Date
    May 2006
    Posts
    7

    Translucency and multi-pass lighting

    Hi!

    I want to render some meshes with translucency and multiple lighting passes. I compute the contribution of each light with a relatively big GLSL shader, and blend it with what already exists in the framebuffer. For fully opaque meshes, this requires rendering a black pass first, then blending with GL_ONE,GL_ONE. It works, and quite well.

    But when rendering translucent meshes, there is a problem. For each such mesh, I first render it with color writes disabled and alpha writes enabled, to get the desired alpha value into the framebuffer. Then I enable blending with GL_DST_ALPHA,GL_ONE_MINUS_DST_ALPHA, enable color writes, disable alpha writes, and render the mesh N more times for N lights.

    Let C_n be the color computed by lighting pass N, let C_b be the color in the framebuffer before blending, and let A be the destination alpha value. For one light, the final color is

    C_1*A+C_b*(1-A)

    This is correct. But for two lights, it is

    C_2*A+(C_1*A+C_b*(1-A))*(1-A)

    which is not correct, because this blends C_1 with the factor (1-A)*A, not A, and it blends C_b with (1-A)^2, not (1-A). It should be

    (C_1+C_2)*A+C_b*(1-A)

    instead. The two lighting passes must be summed up BEFORE blending them with the framebuffer. I also looked at other blend modes, but so far I couldn't find any combination that fits.

    And here lies the problem: I can't sum them up in the framebuffer like I do with opaque meshes, because colors in the framebuffer need to be preserved for blending. I see that current games have translucent polygons and they are correctly lighted (and shadowed), so there must be a way to solve this. But how?

    If anybody knows how to do this, and would care to enlighten me, I would be really, really thankful!

  2. #2
    Advanced Member Frequent Contributor
    Join Date
    May 2005
    Location
    Prague, Czech Republic
    Posts
    913

    Re: Translucency and multi-pass lighting

    The key is to use different blending mode for the first pass than for the additional passes. For example when you have four lights you wish to calculate following equation:

    ((C_4+C_3+C_2+C_1)*A)+(C_b*(1-A))

    That equation can be rewritten as:

    C_4*A + C_3*A + C_2*A + (C_1*A + C_b*(1-A))

    So what you need to do is:
    Draw light 1 with: GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA
    Draw rest of lights with: GL_SRC_ALPHA, GL_ONE

    Of course there is still problem if the mesh is concave and one visible triangle overlaps different visible triangle. In that case this will not work correctly even if your mesh has triangles sorted in such way that they render in correct order.

  3. #3
    Junior Member Newbie
    Join Date
    May 2006
    Posts
    7

    Re: Translucency and multi-pass lighting

    Arrgh! Forget my blabbering. Just ONE minute after I disconnected from the internet, I suddenly saw it. The solution.

    I wanted to have this:

    (C_1+C_2)*A+C_b*(1-A)

    This is equivalent to

    C_1*A+C_2*A+C_b*(1-A)

    Writing it a bit different:

    C_1*A + C_2*A+C_b*(1-A)

    I realized that the part after the first + is nothing else than a blend of C_2 and C_B with the blend mode GL_DST_ALPHA,GL_ONE_MINUS_DST_ALPHA. Adding C_1*A to this term is also easy. If C_2*A+C_b*(1-A) is abbreviated X,

    C_1*A + X*1

    is just a blend of C_1 and X with the blend mode GL_DST_ALPHA,GL_ONE. Repeat for more lights. I implemented it, tested it, and it works flawlessly.

    Now, the thanks have to go to myself for this time :-)

  4. #4
    Junior Member Regular Contributor
    Join Date
    Feb 2003
    Location
    Waltham, MA
    Posts
    125

    Re: Translucency and multi-pass lighting

    Out of curiosity, are you doing A:

    Code :
    for each light
     for each object
    or B:

    Code :
     for each object
      for each light
    It seems to me that while it would blend the top object, the object behind it wouldn't get shaded in subsequent passes if you're doing option A. This is the problem I had hit and have since resorted to a "psuedo-sortless" technique.

    Kevin B

  5. #5
    Junior Member Newbie
    Join Date
    May 2006
    Posts
    7

    Re: Translucency and multi-pass lighting

    I'm doing B. I dropped considering A really soon after it ocured to me that it would not only be incorrect but also slower: material state changes are more expensive than light state changes, I would not want them in the inner loop. Also, building a list of lights per objects is easier (=faster) in my renderer than the reverse.

  6. #6
    Junior Member Regular Contributor
    Join Date
    Feb 2003
    Location
    Waltham, MA
    Posts
    125

    Re: Translucency and multi-pass lighting

    I'm curious why you think A is incorrect? I'm guessing you misunderstood what I said? To be clear, I'm referring to how you treat all objects, not just translucent ones.

    Kevin B

  7. #7
    Junior Member Newbie
    Join Date
    May 2006
    Posts
    7

    Re: Translucency and multi-pass lighting

    Well, you said that behind objects won't get shaded. This is what I would call incorrect.

  8. #8
    Member Regular Contributor
    Join Date
    Jul 2005
    Location
    Germany
    Posts
    306

    Re: Translucency and multi-pass lighting

    i'm having the same problem but i'm not sure what exactly i have to do now. this is how my renderer works:

    - pass 0 renders depth and ambient light
    - glBlendFunc( GL_ONE, GL_ONE )
    - passes 1 to x render all geometry for each light source
    - glDisable( GL_BLEND )

    what exactly do i have to do now? do i need to enable blending for pass 0 as well, which modes do i need for passes 1 to x?

    thanks in advance..

  9. #9
    Junior Member Newbie
    Join Date
    May 2006
    Posts
    7

    Re: Translucency and multi-pass lighting

    Vexator, do you mean for opaque or translucent materials? For the opaque case what you say should be sufficient. For the translucent case, I render the geometry with glColorMask(0,0,0,1) in pass 0, so that the right alpha is written into framebuffer but the color is not touched. This obviously requires a framebuffer with an RGBA pixelformat. Then I set the blend mode to GL_DST_ALPHA,GL_ONE_MINUS_DST_ALPHA for the first lighting pass, and to GL_DST_ALPHA,GL_ONE for the remaining lighting passes.

  10. #10
    Member Regular Contributor
    Join Date
    Jul 2005
    Location
    Germany
    Posts
    306

    Re: Translucency and multi-pass lighting

    i tried what you suggested, and the desired mesh IS drawn translucent now - but all that can be seen through it is the clear color.. not the geometry behind

    i set the clear color to grey and took a screenshot: www.vexator.net/blending_prob.jpg

    (the muzzle flash is mesh with the alpha mask.) thanks!

Posting Permissions

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