Qt Quick 3D - Exemple d'effet personnalisé

Démonstration de l'écriture d'effets de post-traitement personnalisés.

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

L'exemple met en œuvre ses propres effets de post-traitement personnalisés, qui sont ensuite appliqués à la scène via SceneEnvironment::effects. Il démontre à la fois le type d'effets le plus simple qui n'a qu'un fragment shader, et le cas plus avancé avec un vertex et un fragment shader présents, avec des données transmises entre les deux.

L'effet simple consiste à utiliser un seul nuanceur de fragment et à ajouter 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 avec la texture de l'image :

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

Les extraits de shaders dans les fichiers .vert et .frag sont écrits à l'aide des mots-clés intégrés décrits dans la documentation Effect. Les propriétés personnalisées avec des types de base, ainsi que les propriétés avec le type TextureInput sont automatiquement exposées aux shaders en tant qu'uniformes et échantillonneurs.

Le deuxième effet est plus complexe. Il spécifie à la fois un vertex et un fragment shader, 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 fragment shader de cet effet crée une distorsion en modifiant les coordonnées d'échantillonnage. Le calcul utilise center_vec, qui provient du fragment shader. Enfin, le shader ajuste la couleur en utilisant les uniformes uRed et uGreen. Notez que ces uniformes ne doivent pas ê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;
        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.