[Interest] Custom QSGGeometryNode Scene blending issue

Gunnar Sletta gunnar at sletta.org
Fri Jun 24 10:40:11 CEST 2016


Since the window's background is being cleared when you draw the framebuffer, it sounds as the window's default framebuffer is bound at the time of clearing. That or that the FBO is indeed cleared to fully transparent and rendered without blending, thus overwriting the pixels window.

To further debug this, I would have first checked the contents of the FBO, using QOpenGLFramebufferObject::toImage() or using glReadPixels if this is your own FBO, and then look at the blending that happens in the scene graph if that one is ok. What does the QSGTexture instance look like that you use to wrap the FBO. Does it report that there is alpha?

QSG_VISUALIZE=overdraw will tell you whether the FBO is drawn in the scene graph using blending or not.

Or simply use QQuickFramebufferObject, of course :)

cheers,
Gunnar

> On 23 Jun 2016, at 17:26, Roberto Garrido <robertogarridomartin at gmail.com> wrote:
> 
> Gunnar,
> thanks for your detailed response. 
> We don't discard going for the QQuickFramebufferObject soon, but currently what we have is the Item/QSGGeometryNode setup.
> I've been doing some tests, and I cannot manage to get the desired effect. The most silly example I can think of is to clear our buffer with a fully transparent color (as you suggested), then render a fullscreen quad with also a fully transparent color (using premultiplied alpha -> 1, 1 - SRC_ALPHA). That should give us fully transparent item, and the qml scene behind should be shown. But what we see is the desktop itself, not the QML items behind. Does it give you any clue on what could I be doing wrong?
> 
> Our node (derived from QSGGeometryNode) takes a QSGTextureMaterial (with the default shader for this type of material), and we have also activated the QSGMaterial::Blending flag.
> 
> Thanks,
> Robert.
> 
> On 7 June 2016 at 09:41, Gunnar Sletta <gunnar at sletta.org> wrote:
> Hi Roberto,
> 
> The opacity of any geometry node is decided by the opacity that comes out of the fragment shader of its material. Depending on how the alpha logic exists in your custom GL renderer, there are two ways to do this.
> 
> Option 1: If most of the FBO is partially transparent, or if there are bits and pieces that are overlaid on top of the rest of the UI, like controls on a HUD, then you want to render into an FBO with an alpha buffer, clear it with fully transparent, draw your custom GL stuff and then alpha blend the entire FBO on top of the QML scene. You do alpha blending of the fbo content by setting the QSGMaterial::Blending flag and returning a premultiplied alpha color from the fragment shader. The QSGTextureMaterial has a fragment shader that does the right thing.
> 
> Option 2: If you have an opaque FBO with certain sections, say a given rectangle, fully transparent, you can draw the FBO as fully opaque, but create a geometry that excludes the fully transparent region. This has the benefit you will be drawing more opaque stuff which is generally faster for the GPU to handle, compared to blended stuff.
> 
> It is of course possible to do a mixture of 1 and 2, by creating two separate materials, both referring to the FBO. For the fully opaque sections of the FBO, you use an opaque material to draw it which is fast. For the semi-transparent sections of the FBO you use a different geometry node with a material that enables blending. The fully transparent regions are fully excluded from either geometry, so those cost nothing. (something like the MaskedImage I have here: https://github.com/qtproject/playground-scenegraph/tree/master/shapes)
> 
> Btw, if you used QQuickFramebufferObject instead of rolling your own custom Item/node/material, you would get option 1 by default :)
> 
> cheers,
> Gunnar
> 
> > On 06 Jun 2016, at 18:05, Roberto Garrido <robertogarridomartin at gmail.com> wrote:
> >
> > Hi all!
> > We have a custom QQuickItem which in turn creates a custom QSGGeometryNode. We reimplement the QSGGeometryNode's preprocess() method in order to draw our scene to a FrameBufferObject with a texture attached. This OpenGL texture ID is shared with the QSGGeometryNode's material. This way, we can render our custom OpenGL scene into a QML item. So far, so good.
> >
> > However, we want to use alpha blending on some parts of our scene, in order to let the user see the QML items behind our custom item. Something similar to what Item::opacity value is doing, but only for a specific area of our Item. It's like having a hole inside our Item that allows the user to see what's behind. The information about the specific region that should be transparent is handled inside our custom OpenGL renderer.
> >
> > I've been trying to find out what Qt is doing in order to change the opacity of a QML item, with no luck.
> >
> > Any idea on how can we achieve this effect, with our Item/Node configuration?
> > Thanks in advance,
> > Robert.
> >
> > --
> > Website: http://robertogarrido.com
> > Twitter: http://twitter.com/che1404
> > LinkedIn: http://es.linkedin.com/in/robertogarrido/en
> > _______________________________________________
> > Interest mailing list
> > Interest at qt-project.org
> > http://lists.qt-project.org/mailman/listinfo/interest
> 
> 
> 
> 
> -- 
> Website: http://robertogarrido.com
> Twitter: http://twitter.com/che1404
> LinkedIn: http://es.linkedin.com/in/robertogarrido/en




More information about the Interest mailing list