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.
    https://bugreports.qt.io/browse/QTBUG-38279


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.