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

例プロジェクト @ code.qt.io©2024 The Qt Company Ltd. 本書に含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。