Important: Please read the Qt Code of Conduct -

ShaderEffect low texture precision

  • I use QQuickFramebufferObject with GL_RGB32F Internal texture format. Each fragment of the result texture represents it's position in 3d space. Then I postprocess it with
    ShaderEffect, the texture, I get in the shader is a GL_RGB8 representation of the one, the FBO storages. It gives me poor color gradation and bad aliasing effect. How can I access the source 32bit texture?

                    CTile {  //GL_RGB32F
                        anchors.fill: parent
                        layer.enabled: true
                        layer.smooth: true
                        layer.effect: ShaderEffect {
                            fragmentShader: "
                                uniform highp sampler2D source; // this item
                                varying highp vec2 qt_TexCoord0;
                                uniform int mode;
                                highp out vec4 color;
                                void main() {
                                    highp vec4 srccolor = texture2D(source, qt_TexCoord0); //GL_RGB8

    It also cuts negative values.
    Here is one of the effects:
    alt text

  • I guess, I've found the reason of the problem, it's incorrect internal format in shadereffectsource.cpp:

    enum Format {
        Alpha = GL_ALPHA,
        RGB = GL_RGB,
        RGBA = GL_RGBA

    There should be

    enum Format {
        Alpha = GL_R32F,
        RGB = GL_RGB32F,
        RGBA = GL_RGBA32F

    I tried to fix it though qml this way:

    ShaderEffectSource {
        anchors.fill: parent
        sourceItem: item
        format: 0x8814 // GL_RGBA32F
        recursive: false
        hideSource: true

    But I get this error: Invalid property assignment: unknown enumeration
    Why there is a buffer in the middle, wouldn't it be faster to use source fbo directly?
    Can I fix it without recompiling Qt ?
    Is there a way to bind texture from the source fbo right before ShaderEffectItem::renderEffect, so I would be able to use source texture instead of it's bad analog?

  • Hi, Dmitry.
    I believe ShaderEffectSource/layer.enabled will rerender a source item, despite it has a source texture.
    In your case, you can just pass the original texture to the ShaderEffect.

    CTile { 
        id: sourceItem
        visible: false
    ShaderEffect {
        anchors.fill: sourceItem
        property Item source: sourceItem
        fragmentShader: "..."

    Support of RGBA32F in ShaderEffectSource can be useful if the result of shader processing should remain in high precision format. The issue with the request for this feature was created.

Log in to reply