View Issue Details Jump to Notes ] Print ]
IDProjectCategoryView StatusDate SubmittedLast Update
0002347ParaView(No Category)public2005-10-07 14:362011-01-13 17:00
ReporterKen Moreland 
Assigned ToFrançois Bertel 
PlatformOSOS Version
Product Version 
Target VersionFixed in Version 
Summary0002347: SNL: Color alpha pre-multiply
DescriptionOne of the things selecting ordered composite should do is help when rendering transparent surfaces. Unfortunatly, when this option is on, the colors are wrong.

The problem is that ordered compositing does alpha blending of images (generally good for compositing transparent items), but the alpha values in the color buffer are wrong.

The problem is that the blending mode is set to glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA). Although many people think this is appropriate for the Porter & Duff OVER operation, it is not (it gets the color right but the alpha wrong).

There are two ways to get the OVER operation right. The first involves using a special blending mode available in OpenGL 1.3. Unfortunatly, many cheaper implementations still do not support this.

The other way involves setting the blend function to glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA) AND premultiplying the polygon colors by their alpha. For example, the RGBA value of a full intensity red with half opacity is (0.5, 0, 0, 0.5) instead of (1, 0, 0, 0.5) (i.e., the RGB values are "premuliplied" by the alpha).
TagsNo tags attached.
Topic Name
Attached Filespatch file icon ColorAlphaPreMultiply.patch [^] (11,293 bytes) 1969-12-31 19:00 [Show Content]
patch file icon FixDP.patch [^] (3,554 bytes) 1969-12-31 19:00 [Show Content]
patch file icon FixIceTForDepthPeeling.patch [^] (2,920 bytes) 1969-12-31 19:00 [Show Content]
patch file icon AddDepthPeelingSupportToSM.patch [^] (2,580 bytes) 1969-12-31 19:00 [Show Content]


Berk Geveci (administrator)
2005-10-07 14:41

Are we supposed to do something about this or are you (Ken) going to fix it? Should I assign it to someone like Lisa?
Brian Wylie (reporter)
2005-10-07 15:18


Lets push it over to Lisa (if she doesn't mind). Also I've reduced the priority temporarily to 2. This is certainly something we would like in 2.4 but I guess we can't have EVERYTHING! :)
Brian Wylie (reporter)
2006-09-25 12:09

Changing priority to 4, so this gets fixed before 2.6 release.
Ken Moreland (manager)
2006-11-29 09:25

Two notes in case the implementation uses the special blending mode.

In addition to being supported by OpenGL 1.3, there is an old extension, GL_EXT_blend_func_separate, that also provides the special blending mode functions. So, there might be graphics drivers out there that support the extension but not OpenGL 1.3 (and possibly vice versa). Perhaps both should be supported.

Also, if the default blending mode becomes more complicated (requires use of vtkOpenGLExtensionsManager and changes based on driver functionality) there should be a mechanism to easily change the blending mode back to the default. There will be other units (such as the project tetrahedra mapper) that will need to change the blending mode, and it should be easy for it to change back to the default.
Utkarsh Ayachit (administrator)
2006-12-06 10:16

Color is premultiplied by alpha and blending function changed when rendering poly data. Blending function is not changed when rendering polydata with texture since we connot do the alpha premultiplication for colors in the texture." Rendering
/cvsroot/VTK/VTK/Rendering/vtkOpenGLProperty.cxx,v <-- vtkOpenGLProperty.cxx
new revision: 1.35; previous revision: 1.34
/cvsroot/VTK/VTK/Rendering/vtkOpenGLScalarsToColorsPainter.cxx,v <-- vtkOpenGLScalarsToColorsPainter.cxx
new revision: 1.3; previous revision: 1.2
/cvsroot/VTK/VTK/Rendering/vtkScalarsToColorsPainter.cxx,v <-- vtkScalarsToColorsPainter.cxx
new revision: 1.5; previous revision: 1.4
/cvsroot/VTK/VTK/Rendering/vtkScalarsToColorsPainter.h,v <-- vtkScalarsToColorsPainter.h
new revision: 1.3; previous revision: 1.2
Utkarsh Ayachit (administrator)
2006-12-19 15:34

All added patches have been merged to the 2.6 branch.
François Bertel (reporter)
2007-10-22 12:31

I was trying to fix depth peeling to make it work with an vtkImageActor having a texture with an alpha component. This class is also used internally by vtkTextActor3D.

The first bug I saw was with the vtkTextActor3D itself. Regular alpha blending gives a nice result but switching to depth peeling gave me a really fuzzy result, the text was thicker.

The second bug, just with a vtkImageActor, using a yellow image with a alpha ramp (VTkData/Data/alphachannel.png) gave me the expected result with regular alpha blending but a complete yellow
image with depth peeling on, except on the lower-right corner where the alpha is really low (this part was just transparent and discarded by the alpha test (not alpha blending) in vtkOpenGLImageActor)

There is an error in the depth peeling implementation. It is compositing the peels (second stage of the algorithm) with glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA) but when the textured quad
of the image actor is rendered in some peel (first stage of the algorithm), blending is disable. The peel contains the RGBA components of the texture but not alpha-premultiplied because the texture does not
have premultiplied alpha.

I fixed that (on my working directory) by changing the compositing stage to use the "standard" glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA). vtkImageActor renderered correctly then with or without depth peeling.
After this change all the other geometry became darker (with depth peeling only). For good reason: vtkScalarsToColors premultiplied material properties by alpha. With the standard function, there is
now a square alpha so I removed the premultiplication on vtkScalarsToColors and it fixed everything, with or without depth peeling.

Before committing my changes I saw the log about the premultiplied changed and ask Utkarsh if the reason was because of the previous wrong behavior of depth peeling but he told me the premultiplied computation was to fix an issue when compositing in IceT because the alpha was wrong on the final framebuffer (if this one has an alpha channel)

He pointed me to this bug (2347).

It means that right now, rendering of vtkImageActor is wrong anyway without depth peeling because it renders it with a square alpha in the framebuffer. So it should look darker with compositing.

To finally fix everything at the same time, I'd like to use the following function as much as possible
vtkgl::BlendEquationSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA, // RGB

The idea is to:

1. initialize the vtkgl::BlendEquationSeparate function pointer in the renderwindow with this:

vtkOpenGLExtensionManager *extensions=vtkOpenGLExtensionManager::New();
  extensions->LoadCorePromotedExtension("GL_EXT_blend_func_separate"); // see Appendix G of the OpengGL spec.

2. Set the default blending function to be
vtkgl::BlendEquationSeparate(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA, // RGB

if vtkgl::BlendEquationSeparate exists or glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA) if it does not.

2. In OpenGLScalarsToColor, test if the function exists or not

  render not premultiplied material
GLint alphaBits;
glGetIntegerv(GL_ALPHA_BITS, &alphaBits);
 if(alphaBits>0) // framebuffer has some alpha
   render premultiplied material, as it is always the case right now (internal switch to glBlendFunc(GL_ONE,GL_ONE_MINUS_SRC_ALPHA)).
 else // no alpha in framebuffer, don't bother
   render not premultiplied material

Recent OpenGL implementations (Mesa or recent graphic cards) will have the correct result without depth peeling with material or textures because they have vtkgl::BlendEquationSeparate.
Older OpenGL implementation will have correct material alpha but wrong texture alpha in the final framebuffer (*as it is right now* )

I'll add (OpenGL>=1.4 or GL_EXT_blend_func_separate) as a new required extension for depth peeling. Not a big deal as it already requires more advanced feature like GLSL.

It means when depth peeling is on and used, it will not use premultiplied material but the final framebuffer will have the correct premultiplied color with the correct alpha.

Finally, it will require to go through other mappers code like vtkProjectedTetra to make sure, when it switch to its own blending mode, at the end it will switch back to the
default blending mode (vtkgl::BlendEquationSeparate if it exists), probably not by calling glBlendFunc or vtkgl::BlendEquationSeparate but using:

// algorithm here

PS: About the attrib flag to use in glPushAttrib(), the way to find this out is to go read the OpenGL spec and go to the state tables, find the line having BLEND_SRC_ALPHA (for instance), the last column "Attribute"
gives you "color-buffer", then you go back to the "Attribute groups" table and you see that "color-buffer" matches COLOR_BUFFER_BIT.
In addition, glPush/PopAttrib can be faster than reading/writing the state with glGetInteger()/glBlendFunc() because it does not require to send the state value back to the CPU.
François Bertel (reporter)
2007-11-15 10:38

Most of it was solved on 2007-10-27. A nasty bug in vtkOpenGLRenderWindow.cxx was then solved on 2007-11-14 (rev 1.91).

 Issue History
Date Modified Username Field Change
2007-10-22 12:31 François Bertel Assigned To Utkarsh Ayachit => François Bertel
2007-10-22 12:31 François Bertel Status closed => @20@
2007-10-22 12:31 François Bertel Resolution fixed => reopened
2007-10-22 12:31 François Bertel Note Added: 0009524
2007-11-15 10:38 François Bertel Status @20@ => @80@
2007-11-15 10:38 François Bertel Resolution reopened => fixed
2007-11-15 10:38 François Bertel Note Added: 0009682
2009-12-09 14:49 Berk Geveci Project @3@ => ParaView
2009-12-10 18:09 Ken Moreland Status @80@ => closed
2011-01-13 17:00 Source_changeset_attached => VTK master a2bd8391
2011-01-13 17:00 Source_changeset_attached => VTK master 020ef709
2011-06-16 13:09 Zack Galbreath Category => (No Category)

Copyright © 2000 - 2018 MantisBT Team