QtQuick3D在Qt 6.1中引入了对实例渲染的支持。这是图形处理器(GPU)的一项功能,可以极大地提高性能。实例化渲染可以通过一次绘制调用来渲染大量项目。
Qt组件推荐:
- QtitanRibbon| 下载试用: 遵循Microsoft Ribbon UI Paradigm for Qt技术的Ribbon UI组件,致力于为Windows、Linux和Mac OS X提供功能完整的Ribbon组件。
- QtitanChart | 下载试用 :是一个C ++库,代表一组控件,这些控件使您可以快速地为应用程序提供漂亮而丰富的图表。并且支持所有主要的桌面
QtQuick3D在Qt 6.1中引入了对实例渲染的支持。这是图形处理器(GPU)的一项功能,可以极大地提高性能。实例化渲染可以通过一次绘制调用来渲染大量项目。(对于熟悉低级OpenGL的人来说,函数glDrawElementsInstanced是一个示例。)

在我的开发机器上使用这个新的实例功能,QtQuick3D可以以每秒60帧(FPS)的速度渲染一百万个立方体,仅使用2%的CPU时间。同样的场景在Qt 6.0中使用API重新创建,使用Repeater3D生成立方体,在一万个立方体时开始挣扎:只能管理42 FPS,并且使用100%的CPU。
下面是上图所示的简单例子的源代码,创建一个场景,显示20000个位置、颜色和旋转随机的金属甜甜圈形状。
import QtQuick3Dimport QtQuick3D.Helpersimport QtQuickWindow { width: 800 height: 450 visible: true View3D { anchors.fill: parent camera: camera environment: SceneEnvironment { backgroundMode: SceneEnvironment.SkyBox lightProbe: Texture { source: "skybox.hdr" } probeExposure: 3 } PerspectiveCamera { id: camera position: Qt.vector3d(0, 300, 500) eulerRotation.x: -25 } DirectionalLight { eulerRotation.x: -30 eulerRotation.y: -70 } RandomInstancing { id: randomTable instanceCount: 20000 position: InstanceRange { from: Qt.vector3d(-5000, -2000, -9000); to: Qt.vector3d(5000, 200, 500) } rotation: InstanceRange { from: Qt.vector3d(20, 0, -45); to: Qt.vector3d(60, 0, 45) } color: InstanceRange { from: Qt.rgba(0.1, 0.1, 0.1, 1); to: Qt.rgba(1, 1, 1, 1) } } Model { instancing: randomTable source: "torus.mesh" materials: PrincipledMaterial { metalness: 1.0; roughness: 0.2; baseColor: "#ffffff" } } }}
API
实例化API的主要原理是明确的。它不会尝试自动检测现有API中实例化的机会。
起点是Instancing对象:一个定义如何呈现每个副本的表。修改是变换(位置,旋转和比例);颜色(与模型材料混合);以及可用于自定义材料的自定义数据。在6.1中,有两种现成的QML类型:
-
InstanceList允许您枚举所有实例并绑定到每个实例的属性。
-
如上所示,RandomInstancing提供了一种快速测试和原型化的方法。
其他种类的实例表可以使用C ++ API轻松定义。我们将在以后的版本中添加其他QML实例化表。可能包括由数据模型定义的表,以及从外部源读取的表。
一旦定义了表,就可以通过设置其实例化属性将其应用于模型。单个表可以同时与多个不同模型一起使用。
通过编写自定义着色器代码,可以使用实例化 来控制其他属性,例如基于物理的渲染的变量,骨骼动画权重,变形或可以用自定义材质表达的任何其他内容。当前,实例化表中的自定义数据被限制为四个浮点数。
Qt 6.1中的custominstancing示例使用自定义材料和用C ++实现的实例表来绘制一个复杂的场景,该场景仅包含一个重复了多次的单个多维数据集:

权衡取舍
谁不希望性能提高100倍们应该把所有事情都实例化吗然,实例化并非万能的灵丹妙药,它也不总是适合这项工作的合适工具。以下是一些注意事项:
-
首先:实例化是指使用定义明确的修改来渲染同一模型的大量副本。当绘制少量非常不同的东西时,它将无济于事。
-
主要的改进是在CPU和内存使用方面。GPU的性能好坏参半:我们通过减少绘制调用的次数以及可能的数据量来获得改进,但是顶点着色器更加复杂,因为它需要在每个实例中进行多次转换。
-
渲染单个模型时,QtQuick3D将分别对不透明和半透明的对象进行排序,并以最佳顺序对其进行渲染。使用实例化时,GPU将按照实例化表指定的顺序进行渲染,而QtQuick3D不会为您对该表进行排序。这样可以节省大量CPU时间,但有两个后果:
-
不透明的对象将不会以最佳顺序进行渲染,这意味着同一像素可能会被多次写入,从而导致片段着色器进行更多工作,并可能使性能变差
-
对于半透明的对象,仅当项目从前向后渲染时,混合才是正确的。如果副本之间的重叠不太多,或者每个副本的不透明度很低,那么这可能不是一个大问题。但是,在最坏的情况下,它可能看起来像这样:
-
技术预览
Qt 6.1中的技术预览中提供了实例化,Qt 6.2中将完全支持实例化。我们不打算对API进行重大更改,但是根据您的反馈可能会进行较小的更改。二进制兼容性可能不会保留:最有可能更改的部分是,当前GPU实例化表的二进制布局已反映在公共C ++ API中。
如果您正在考虑将实例渲染与Qt 6.2一起使用,那么现在是开始的最佳时机。您的代码最多只需要很小的修改,您的反馈就可以帮助我们改进Qt 6.2,从而更好地支持您的用例。


标签:
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!