Qt Quick 3D - Ejemplo de efecto personalizado

Demuestra la escritura de efectos de post-procesamiento personalizados.

Escena deformada con logotipo Qt rosa y suelo a cuadros que muestra efectos de posprocesamiento personalizados.

El ejemplo implementa sus propios efectos de post-procesamiento personalizados, que luego se aplican en la escena a través de SceneEnvironment::effects. Demuestra tanto el tipo más simple de efectos que sólo tienen un fragment shader, como el caso más avanzado con un vertex y fragment shader presentes, con datos pasados entre los dos.

El efecto simple es utilizar sólo un fragment shader, y la adición de una textura de entrada de un archivo de imagen:

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"
        }
    }
}

Este efecto utiliza un fragment shader muy simple, simplemente tomando la textura de entrada que contiene la escena, y multiplicándola con la textura de la imagen:

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

Los fragmentos de shader en los archivos .vert y .frag están escritos usando las palabras clave incorporadas como se describe en la documentación Effect. Las propiedades personalizadas con tipos básicos, así como las propiedades con el tipo TextureInput se exponen automáticamente a los shaders como uniformes y muestreadores.

El segundo efecto es más complejo. Especifica tanto un sombreador de vértices como uno de fragmentos, así como dos propiedades: uRed y uGreen, con una animación en 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 ]
    }
}

El fragment shader para este efecto crea una distorsión modificando las coordenadas de muestreo. El cálculo utiliza center_vec, que proviene del fragment shader. Finalmente, el shader ajusta el color usando los uniformes uRed y uGreen. Tenga en cuenta que estos uniformes no tienen que ser declarados en el 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;
}

Proyecto de ejemplo @ 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.