实例渲染(Instanced Rendering)

Instanced Rendering

实例渲染

Introduction

介绍

Qt Quick 3D supports instancing of Model objects. Instancing refers to a technique where one object is rendered multiple times with a single draw call. (For example the OpenGL function glDrawElementsInstanced.)

​Qt Quick 3D支持模型对象的实例化。实例化是指一种通过一次绘制调用多次渲染一个对象的技术。(例如OpenGL函数glDrawElementsInstanced。)

Instancing allows duplicating a model with variations. In contrast to using a Repeater3D, the model and its graphics resources are only allocated once. The rendering of the duplicated instances is done at a low level by the GPU. Depending on the complexity of the model, this can give a performance improvement of several orders of magnitude.

​实例化允许复制具有变体的模型。与使用Repeater3D相比,模型及其图形资源只分配一次。重复实例的渲染由GPU在低级别完成。根据模型的复杂性,这可以使性能提高几个数量级。

In practice, instancing is done by defining a table that specifies how each instance is modified relative to the base model.

在实践中,实例化是通过定义一个表来完成的,该表指定了每个实例相对于基础模型的修改方式。

Instancing API

实例化API

The main principle of the instancing API is that it is explicit: It doesn't try to autodetect opportunities for instancing within the existing API. Instead, each model is marked individually by setting its instancing property to reference an Instancing object. The same Instancing object can be used on multiple models at the same time.

​实例化API的主要原理是它是明确的:它不试图在现有的API中自动检测实例化的机会。相反,每个模型都通过将其实例化属性设置为引用实例化对象来单独标记。同一实例化对象可以同时用于多个模型。

The Instancing object specifies a table that defines how each copy is rendered. The available modifications are:

实例化对象指定了一个表,该表定义了每个副本的呈现方式。可用的修改包括:

  • transformation: position, rotation, and scale
  • 变换:位置、旋转和缩放
  • color: a color that is blended with the model’s material
  • 颜色:与模型材质混合的颜色
  • custom data: data that can be used by custom materials
  • 自定义数据:可由自定义材质使用的数据

Qt provides three QML types that inherit from Instancing:

Qt提供了三种继承自实例化的QML类型:

  • InstanceList enumerates all instances and allows binding to the properties of each instance.
  • InstanceList枚举所有实例,并允许绑定到每个实例的属性。
  • RandomInstancing provides a way to quickly test and prototype by generating random instances within defined bounds.
  • RandomInstancing提供了一种通过在定义的边界内生成随机实例来快速测试和原型化的方法。
  • FileInstancing reads an instance table from an external file.
  • FileInstating从外部文件读取实例表。

The instancing example shows how to create a scene using the QML API.

​实例示例演示了如何使用QML API创建场景。

Other kinds of instance tables can be defined in C++ by subclassing QQuick3DInstancing. For example, the particle system uses its own instancing table internally. It is available as ModelParticle3D.instanceTable.

​其他类型的实例表可以在C++中通过子类QQuick3DInstang来定义。例如,粒子系统在内部使用自己的实例化表。它以ModelParticle3D.instanceTable的形式提供。

By writing custom shader code, it is possible to use instancing to control additional properties, such as variables for physically based rendering, skeletal animation weights, distortion, or anything else that can be expressed with custom materials. The custom data in the instancing table consists of four floating point numbers.

通过编写自定义着色器代码,可以使用实例化来控制其他属性,例如基于物理的渲染变量、骨架动画权重、失真或可以用自定义材质表示的任何其他属性。实例化表中的自定义数据由四个浮点数组成。

The custom instancing example shows how to combine custom materials and an instance table implemented in C++.

​自定义实例化示例显示了如何组合自定义材质和用C++实现的实例表。

Alpha-blending and instancing

Alpha混合和实例化

Correct alpha blending requires that semi-transparent objects are rendered back-to-front. For this reason, QtQuick3D sorts opaque and semi-transparent objects separately, and renders them in the correct order. With instancing, however, the GPU will render the instances in the order specified by the instancing table, if depth-sorting is not turned on. For performance reasons, QtQuick3D does not sort the table by default as it can take long time with large number of instances. This means that if semi-transparent instances overlap with each other, or with other semi-transparent objects, the results may look wrong. In general, the error is less visible when the opacity is low.

​正确的通道混合要求半透明对象从后到前渲染。因此,QtQuick3D将不透明和半透明对象分别排序,并以正确的顺序渲染它们。然而,使用实例化时,如果未启用深度排序,GPU将按照实例化表指定的顺序渲染实例。出于性能原因,QtQuick3D默认情况下不会对表进行排序,因为大量实例可能需要很长时间。这意味着,如果半透明实例彼此重叠,或与其他半透明对象重叠,结果可能会看起来不正确。一般来说,当不透明度较低时,错误不太明显。

Fully opaque objects together with non-overlapping semi-transparent objects will always be rendered correctly, since Qt uses depth buffer testing to avoid drawing behind opaque objects. However, the lack of sorting has potential performance implications for opaque objects: They may not be rendered in the optimal order, meaning that the same pixel can be written multiple times, making more work for the fragment shader.

完全不透明的对象和不重叠的半透明对象将始终正确渲染,因为Qt使用深度缓冲区测试来避免在不透明对象后面绘制。然而,缺乏排序对不透明对象具有潜在的性能影响:它们可能无法以最佳顺序渲染,这意味着同一像素可以多次写入,从而为片段着色器带来更多工作。

The renderer does not inspect the contents of the instancing table, so it must be specified explicitly when an instance table contains semi-transparent alpha values: Set the hasTransparency property to to true to make sure that the renderer enables alpha blending. This applies to all the instances: Even fully opaque instances will be rendered without depth testing, potentially causing visible errors.

​渲染器不会检查实例化表的内容,因此当实例表包含半透明alpha值时,必须明确指定:将hasTransparency属性设置为true,以确保渲染器启用alpha混合。这适用于所有实例:即使是完全不透明的实例也会在没有深度测试的情况下渲染,这可能会导致可见的错误。

The rendering order relative to the rest of the scene can be adjusted by setting the depth bias of the model.

​可以通过设置模型的深度偏差来调整相对于场景其余部分的渲染顺序。

Transforms and instancing

变换和实例化

Each instance has its own transform in the instance table. This is combined with the transforms on the instanced model. This is slightly complex, since there are several use cases:

每个实例在实例表中都有自己的转换。这与实例化模型上的变换相结合。这有点复杂,因为有几个用例:

  • Doing a transform on the model that is applied to each individual instance. This allows cheap animations, for example by rotating all instances at once without having to change the instance table.
  • 对应用于每个单独实例的模型进行变换。这允许廉价的动画,例如通过一次旋转所有实例而无需更改实例表。
  • Transforming the entire group of instances at once.
  • 一次变换整个实例组。
  • Instancing a model hierarchy.
  • 实例化模型层次结构。

To support all these cases, The model’s transform is split into two parts: the local instance transform, and the global instance transform. Conceptually, instancing is performed like this:

为了支持所有这些情况,模型的变换分为两部分:局部实例转换和全局实例转换。从概念上讲,实例化是这样执行的:

  • First the model is transformed according to the local instance transform.
  • 首先,根据局部实例转换对模型进行变换。
  • Then each instance is calculated by applying the instance table transform
  • 然后,通过应用实例表变换来计算每个实例
  • Finally, the whole group of instanced objects is transformed according to the global instance transform.
  • 最后,根据全局实例变换对整个实例化对象组进行变换。

By default, the local instance transform of a model consists of the model’s scale and rotation, while the rest goes into the global instance transform.

默认情况下,模型的局部实例变换由模型的缩放和旋转组成,而其余部分则进入全局实例变换。

This can be controlled by setting the model’s instanceRoot property. This defines the origin of the instance’s coordinate system. The most common use is when instancing a hierarchy of models. For example, a sphere orbiting around a cube:

​这可以通过设置模型的instanceRoot属性来控制。这定义了实例坐标系的原点。最常见的用途是实例化模型的层次结构。例如,围绕立方体旋转的球体:

Model {
    id: cube
    instancing: someInstanceTable
    source: "#Cube"
    materials: DefaultMaterial { diffuseColor: "lightgray" }
    Node {
        Model {
            source: "#Sphere"
            instanceRoot: cube
            instancing: cube.instancing
            x: 150
            materials: DefaultMaterial { diffuseColor: "gray" }
        }
        NumberAnimation on eulerRotation.y {
            from: 0
            to: 360
            duration: 4000
            loops: Animation.Infinite
        }
    }
}

The instanceRoot is necessary to specify that the sphere instance should be positioned as if it were an element of the cube. Each model in a hierarchy still needs to specify the instancing property: in normal cases they should all be set to the same Instancing object.

instanceRoot是指定球体实例应定位为立方体元素所必需的。层次结构中的每个模型仍然需要指定实例化属性:在正常情况下,它们都应该设置为相同的实例化对象。

instanceRoot can also be used when instancing a single model. For example, a cylinder rotating around an off-center point:

实例化单个模型时也可以使用instanceRoot。例如,一个围绕偏心点旋转的圆柱体:

 Node {
    id: parentNode
    Model {
        source: "#Cylinder"
        instanceRoot: parentNode
        instancing: anotherInstanceTable
        x: 25
        materials: DefaultMaterial { diffuseColor: "white" }
    }
    NumberAnimation on eulerRotation.y {
        from: 0
        to: 360
        duration: 1000
        loops: Animation.Infinite
    }
}

Picking and instancing

拾取和实例化

Picking is a mechanism that enables selecting a model from a user interface interaction. With instanced rendering, there are several representations of the same model, so the pick result will include an instance index. Instanced picking is enabled by setting the pickable property on the base model.

拾取是一种能够从用户界面交互中选择模型的机制。使用实例化渲染,同一模型有多种表示形式,因此拾取结果将包括一个实例索引。通过在基础模型上设置可拾取属性来启用实例化拾取。

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值