Qt Quick 3D - カスタムエフェクトの例

カスタムポストプロセッシングエフェクトの作成例です。

この例では、独自のカスタムポストプロセッシングエフェクトを実装し、SceneEnvironment::effects を介してシーンに適用します。フラグメントシェーダだけを持つ最も単純なタイプのエフェクトと、頂点シェーダとフ ラグメントシェーダの両方が存在し、両者の間でデータが受け渡される、より高度なケー スの両方を示しています。

単純なエフェクトは、フラグメントシェーダを 1 つだけ使用し、 画像ファイルからテクスチャ入力を追加したものです:

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

このエフェクトは非常にシンプルなフラグメントシェーダを使い、シーンを含む入力テクスチャを受け取り、イメージテクスチャと乗算するだけです:

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

.vert.frag ファイルにあるシェーダースニペットは、Effect ドキュメントで説明されているように、組み込みキーワードを使って書かれています。基本タイプを持つカスタムプロパティや、TextureInput タイプを持つプロパティは、ユニフォームやサンプラーとしてシェーダーに自動的に公開されます。

2つ目のエフェクトはより複雑です。頂点シェーダとフラグメントシェーダの両方と、uReduGreen の 2 つのプロパティを指定し、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 ]
    }
}

このエフェクトのフラグメントシェーダは、サンプリング座標を 変更することによって歪みを作ります。計算はフラグメントシェーダから来るcenter_vec を使います。最後に、シェーダはuReduGreen のユニフォームを使って色を調整します。これらのユニフォームはシェーダで宣言する必要がないことに注意してください:

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

プロジェクト例 @ code.qt.io

© 2025 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.