Qt 3D: ワイヤフレーム QML の例

シングルパスのワイヤフレームレンダリング手法を実装した Qt 3D QML アプリケーションです。

Qt 3D Wireframe Renderingは、シングルパスワイヤフレームレンダリングメソッドを実装するためのカスタムシェーダセットを使用して、単一のエンティティ(三つ葉の結び目)を描画する方法を説明します。

例を実行する

Qt Creator からサンプルを実行するには、Welcome モードを開き、Examples からサンプルを選択します。詳細については、Building and Running an Example を参照してください。

エンティティの作成

レンダラのアスペクトは、ジオメトリ、マテリアル、およびオプションでトランスフォームを持つエンティティを探します。これらはすべて QComponent のサブクラスとして指定され、MeshMaterialTransform の形式で QML エンジンにエクスポートされます。これらのコンポーネントを使用して、TrefoilKnot.qmlのカスタムQMLアイテムを作成します。

まず、Qt.vector3d()のようなEntity 型と値型のヘルパーを提供するQt3D 2.0 モジュールをインポートします。また、レンダラー・アスペクトによってピックアップされたコンポーネントやその他の型を提供するQt3D.Renderer モジュールもインポートします:

import Qt3D.Core 2.0
import Qt3D.Render 2.0

他のアスペクトのコンポーネントを使用するには、対応するQMLモジュールもインポートする必要があります。

他のアスペクトのコンポーネントを使用するには、対応するQMLモジュールもインポートする必要があります。次に、Entity 型をカスタムQML型のルート要素として使用し、QMLの他の型と同じように、いくつかのカスタムプロパティを公開します:

Entity {
    id: root

    property real x: 0.0
    property real y: 0.0
    property real z: 0.0
    property real scale: 1.0
    property real theta: 0.0
    property real phi: 0.0
    property Material material

Entity 、コンポーネントの集約だけでなく、子オブジェクトをグループ化することもできます。これは Qt Quick 2 におけるItem 型の使い方に似ています。

変換の指定

Transform コンポーネントとMesh コンポーネントをインスタンス化します。Transform コンポーネントは、OpenGL パイプラインで描画するときにレンダラーがジオメトリをどのように変換するかを指定します。順番に並んだ変換のセットを 1 つのTransform コンポーネントにまとめます。この情報は、標準の名前付きユニフォーム変数を通じて、シェーダが自動的に利用できるようになります:

    Transform {
        id: transform
        translation: Qt.vector3d(root.x, root.y, root.z)
        rotation: fromEulerAngles(theta, phi, 0)
        scale: root.scale
    }

頂点ごとの動的データのロード

Mesh コンポーネントは非常にシンプルです。そのソースプロパティを使用して、Wavefront Obj フォーマットのファイルから静的なジオメトリセット(頂点位置、法線ベクトル、テクスチャ座標など)をロードします。このデータはBlenderアプリケーションからエクスポートしたものです。

    Mesh {
        id: mesh
        source: "qrc:/assets/obj/trefoil.obj"
    }

Mesh 要素に加えて、Qt 3D ではタスクベースのエンジンから呼び出される C++ フックによって、頂点ごとの属性データを動的に生成することもできます。

コンポーネントの集約

しかし、単にコンポーネントをインスタンス化するだけでは十分ではありません。コンポーネントがエンティティに特別な動作を与えるためには、エンティティはそのコンポーネントプロパティによってコンポーネントを集約する必要があります:

    components: [ transform, mesh, root.material ]

これにより、複数のエンティティ間でコンポーネントを簡単に共有できるようになる。この例では、TrefoilKnotカスタムタイプに含まれるトランスフォームとメッシュのコンポーネントがある。最後のコンポーネント(Material 型)は、TrefoilKnot カスタムタイプのプロパティによって提供されます。エンティティの外観は後でカスタマイズします。

カメラからのレンダリング

main.qmlでTrefoilKnotカスタム型を使用して、三つ葉結び目を画面に描画します。

TrefoilKnot.qmlと同じimport文を使用し、アニメーションに必要なQt Quickモジュールの名前空間importを追加しています:

import QtQuick 2.1 as QQ2
import Qt3D.Core 2.0
import Qt3D.Render 2.0

ルート型としてEntity 型を使用するのは、単にその子の親として機能するためです。この意味で、Entity 型はItem 型とよく似ています:

import Qt3D.Input 2.0
import Qt3D.Extras 2.0

Entity {
    id: root

RendererSettingsコンポーネントは、ForwardRenderer 型を使用して、C++コードに触れることなくレンダラーを完全に設定します:

    // Render from the mainCamera
    components: [
        RenderSettings {
            activeFrameGraph: ForwardRenderer {
                id: renderer
                camera: mainCamera
            }
        },
        // Event Source will be set by the Qt3DQuickWindow
        InputSettings { }
    ]

BasicCamera型は、仮想カメラを表す組み込みのCamera 型の些細なラッパーです。BasicCamera型は、近景と遠景、視野、アスペクト比、投影タイプ、位置、向きなどのプロパティを持っています:

    BasicCamera {
        id: mainCamera
        position: Qt.vector3d( 0.0, 0.0, 15.0 )
    }

Configuration 型は、アスペクトとコンポーネントを使用する適切な実装が完成するまでの間、マウスでカメラを制御するための一時的な回避策を提供します:

    FirstPersonCameraController { camera: mainCamera }

複数のカメラを使用し、シーンレンダリングのすべてまたは一部でフレームグラフを使用してそれらを選択することは簡単です。

マテリアルのマッピング

Qt 3D には、堅牢で非常に柔軟なマテリアル・システムがあり、複数のレベルのカスタマイズが可能です。WireframeMaterialカスタムタイプを使用して、Material タイプをラップします:

    WireframeMaterial {
        id: wireframeMaterial
        effect: WireframeEffect {}
        ambient: Qt.rgba( 0.2, 0.0, 0.0, 1.0 )
        diffuse: Qt.rgba( 0.8, 0.0, 0.0, 1.0 )

次に、TrefoilKnot型をインスタンス化し、それにマテリアルを設定します:

    TrefoilKnot {
        id: trefoilKnot
        material: wireframeMaterial
    }

これで、Qt 3D エンジンとレンダラーのアスペクトは、指定したマテリアルを使ってメッシュをレンダリングするのに十分な情報を得ました。

アニメーション要素の使用

TrefoilKnot 型と WireframeMaterial 型のプロパティをアニメーションさせるために、Qt Quick 2 が提供するアニメーション要素を使用します。型のコンポーネントのプロパティは、QMLプロパティバインディングメカニズムを使って更新されます:

        QQ2.SequentialAnimation {
            loops: QQ2.Animation.Infinite
            running: true

            QQ2.NumberAnimation {
                target: wireframeMaterial;
                property: "lineWidth";
                duration: 1000;
                from: 0.8
                to: 1.8
            }

            QQ2.NumberAnimation {
                target: wireframeMaterial;
                property: "lineWidth";
                duration: 1000;
                from: 1.8
                to: 0.8
            }

            QQ2.PauseAnimation { duration: 1500 }
        }

プロパティの更新は、QNode ベースクラスによって通知され、レンダラーのアスペクト内の対応するオブジェクトに自動的に送信されます。プロパティの更新は、 ベースクラスによって通知され、レンダラー アスペクトの対応するオブジェクトに自動的に送信されます。レンダラーは、プロパティの更新を GLSL シェーダプログラムのユニフォーム変数の新しい値に変換します。

例を実行すると、ワイヤーフレームの線の幅が脈動する三つ葉の結び目が表示されます。力仕事はすべて GPU が行っています。CPU は、プロパティのアニメーションを実行し、シーングラ フとフレームグラフを生の OpenGL 呼び出しに変換するだけです。

カスタムシェーダプログラムとマテリアルを使って、GPU上でアニメーションさせることも可能です。

サンプルプロジェクト @ code.qt.io

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