Qt 3D:线框 QML 示例

Qt 3D QML 应用程序实现了单程线框渲染方法。

Qt 3D Wireframe Rendering 演示了如何使用一组自定义着色器来实现单程线框渲染方法,从而绘制单个实体(一个三叶草结)。

运行示例

要从 Qt Creator,打开Welcome 模式,然后从Examples 中选择示例。更多信息,请参见Qt Creator: 教程:构建并运行

创建实体

渲染器会寻找具有几何形状、材质和可选变换的实体。这些都以 QComponent 子类的形式指定,并以Mesh,Material, 和Transform 的形式导出到 QML 引擎。我们使用这些组件在TrefoilKnot.qml 中创建一个自定义 QML 项目。

我们首先导入Qt3D 2.0 模块,该模块提供Entity 类型和值类型助手,如 Qt.vector3d()。此外,我们还导入了Qt3D.Renderer 模块,该模块提供了组件以及渲染器所使用的其他类型:

import Qt3D.Core 2.0
import Qt3D.Render 2.0

要使用其他方面的组件,我们也需要导入相应的 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 类型还可用于将子对象分组。这类似于Item 类型在Qt Quick 2 中的用法。

指定变换

我们实例化了一个Transform 组件和一个Mesh 组件。Transform 组件指定渲染器在使用 OpenGL 管道绘制几何图形时应如何变换几何图形。我们将一组有序的变换组合到一个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 中相同的导入语句,并为动画所需的Qt Quick 模块添加了一个命名导入:

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 {
        id: mainCamera
        position: Qt.vector3d( 0.0, 0.0, 15.0 )
    }

Configuration 类型提供了一种临时解决办法,在使用方面和组件的适当实现完成时,可以用鼠标控制摄像头:

    FirstPersonCameraController { camera: mainCamera }

使用多个摄像机并在全部或部分场景渲染中使用帧图在它们之间进行选择是非常简单的。

贴图材质

Qt 3D 我们使用的是WireframeMaterial(线框材质)自定义材质系统。我们使用 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 引擎和渲染器方面已经掌握了足够的信息,可以使用我们指定的材质最终渲染我们的网格。

使用动画元素

我们使用Qt Quick 2 提供的动画元素对 TrefoilKnot 和 WireframeMaterial 类型的属性进行动画处理。类型组件的属性是通过 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

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