Qt Quick 3D - Exemple d'effet personnalisé

Illustre la création d'effets de post-traitement personnalisés.

Scène déformée avec le logo Qt rose et un sol en damier, mettant en avant des effets de post-traitement personnalisés

Cet exemple implémente ses propres effets de post-traitement personnalisés, qui sont ensuite appliqués à la scène via SceneEnvironment::effects. Il présente à la fois le type d’effet le plus simple, qui ne comporte qu’un shader de fragment, et le cas plus avancé où un shader de sommet et un shader de fragment coexistent, avec un échange de données entre les deux.

L'effet simple utilise uniquement un shader de fragment et ajoute une texture provenant d'un fichier image :

Effect {
    id: eff1
    property TextureInput tex: TextureInput {
        id: qtLogo
        texture: Texture { source: "qt_logo_rect.png" }
    }
    passes: Pass {
        shaders: Shader {
            id: fs1
            stage: Shader.Fragment
            shader: "effect.frag"
        }
    }
}

Cet effet utilise un shader de fragment très simple, qui se contente de prendre la texture d’entrée contenant la scène et de la multiplier par la texture de l’image :

void MAIN()
{
    vec4 c = texture(tex, TEXTURE_UV);
    FRAGCOLOR = c * texture(INPUT, INPUT_UV);
}

Les extraits de shader dans les fichiers .vert et .frag sont écrits à l’aide des mots-clés intégrés, comme décrit dans la documentation Effect. Les propriétés personnalisées de types de base, ainsi que les propriétés de type TextureInput, sont automatiquement exposées aux shaders sous forme d’uniformes et d’échantillonneurs.

Le deuxième effet est plus complexe. Il spécifie à la fois un shader de sommet et un shader de fragment, ainsi que deux propriétés : uRed et uGreen, avec une animation sur uRed:

Effect {
    id: eff2
    property real uRed: 0.0
    SequentialAnimation {
        running: radioEff2.checked || radioEff3.checked
        loops: Animation.Infinite
        NumberAnimation { target: eff2; property: "uRed"; from: 0; to: 1; duration: 2000 }
        NumberAnimation { target: eff2; property: "uRed"; from: 1; to: 0; duration: 2000 }
    }
    property real uGreen: 1.0
    Shader {
        id: vs2
        stage: Shader.Vertex
        shader: "effect2.vert"
    }
    Shader {
        id: fs2
        stage: Shader.Fragment
        shader: "effect2.frag"
    }
    passes: Pass {
        shaders: [ vs2, fs2 ]
    }
}

Le shader de fragment de cet effet crée une distorsion en modifiant les coordonnées d’échantillonnage. Le calcul utilise ` center_vec`, une variable `VARYING` définie par le shader de sommet qui contient le vecteur, corrigé en fonction du rapport d’aspect, reliant le centre de l’écran au fragment actuel. Enfin, le shader ajuste la couleur à l’aide des uniformes uRed et uGreen. Notez que ces uniformes n’ont pas besoin d’être déclarés dans le shader :

VARYING vec2 center_vec;

void MAIN()
{
    float radius = 0.25;
    float dist_to_center = length(center_vec) / radius;
    vec2 texcoord = INPUT_UV;
    if (dist_to_center <= 1.0) {
        float rotation_amount = (1.0 - dist_to_center) * (1.0 - dist_to_center);
        float r = radians(360.0) * rotation_amount / 4.0 * FRAMEBUFFER_Y_UP;
        float cos_r = cos(r);
        float sin_r = sin(r);
        mat2 rotation = mat2(cos_r, sin_r, -sin_r, cos_r);
        texcoord = vec2(0.5, 0.5) + rotation * (INPUT_UV - vec2(0.5, 0.5));
    }
    vec4 c = texture(INPUT, texcoord);
    c.r *= uRed;
    c.g *= uGreen;
    FRAGCOLOR = c;
}

Exemple de projet @ code.qt.io

© 2026 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.