Qt 3D Overview

Qt3D建立的目标是能够让开发者快速地创建3D场景,通过各式各样的渲染技术来达到3D交互的场景。Qt3D除了和Qt一样跨平台之外,还能够选择OpenGL的具体实现,定制GLSL,从而能够根据不同性能的机器,来调整渲染效果。

Qt3D提供一个可充分配置的渲染器,开发人员通过渲染器可快速实现任何渲染管线。而且除了渲染外,Qt3D还提供一个近实时仿真的通用框架。

Qt3D由一个核心模块和附加模块组成。这些附加模块提供特定方面的功能,包括物理模型模块、音频模块、碰撞模块、人工智能模块和路径搜索模块。

Basic3D Features

Qt3D是一个可绘制并移动3D模型的框架,也可以移动相机。框架支持如下基本特征:

  • C++QtQuick应用提供2D3D渲染

  • 网状

  • 材质

  • 着色器

  • 阴影贴图

  • 环境碰撞

  • 高动态范围(HDR)

  • 延迟渲染

  • 多重纹理

  • 实例渲染

  • 统一缓冲对象(UBO)

Materials

Qt3D提供的材质系统稳定且灵活,用户可以多级定制。它可以在不同平台或者不同OpenGL版本上实现材质渲染,通过传递不同的状态集进行多次渲染,提供不同级别的参数覆盖,允许在着色器间切换。这些特征通过C++或者使用QML属性绑定来实现。

GLSL着色器程序中,材质类型属性能够通过统一变量映射,而着色器程序可在程序中来指定。

关于材质的例子,可参考 Qt3D: Materials C++ Example and Qt3D: Materials QML Example.

Shaders

Qt3D支持所有的OpenGL可编程渲染管线阶段:顶点、排列控制、排列计算、几何和片段着色器。计算着色器(CS)将在以后的版本中支持。

着色器的例子可参考:theSimple Shaders QML Example, Qt3D: Tessellation Modes QML Example, Qt3D: Shadow Map QML Example, Qt3D: Wireframe QML Example, and Qt3D: Wave QML Example.

ShadowMapping

OpenGL并不直接支持阴影效果,但已提供多种实现技术。阴影贴图可以在非常低的性能损耗下产生不错的阴影效果。

阴影贴图通过二次渲染实现。在第一次渲染时产生阴影信息,在第二次渲染时通过特殊渲染技术产生场景,同时利用第一次渲染时产生的信息绘制阴影。

阴影贴图技术的原理就是只照亮最靠近光源的片段。其他片段的光线被遮挡,显示阴影效果。

因此,在第一次渲染阶段,以光源为视点绘制场景。在这个光照空间中,存储的信息仅仅只是最接近光源的片段实例。在OpenGL的术语中,这个实例对应一个缓冲对象(FBO),包含深度纹理信息。实际上,从眼睛到实例的距离就是深度的定义,OpenGL的默认深度测试实际上只存储最接近光源片段的深度。

颜色纹理附件甚至都不需要,对于阴影片段这是不必要的,仅仅只需要计算深度。

如下图片显示了带阴影贴图的飞机和三叶形纽结的场景:


下图展示了一个夸张的阴影贴图纹理场景:

图片显示了以光源为视点的场景渲染深度。阴暗颜色代表阴影深度(即靠近摄像机)。 此 光源放置在目标物体的上面,主摄像机的右边(与第一个截屏比较)。玩具飞机比其他目标更靠近摄像机。

当阴影贴图生成后,第二阶段的渲染就完成了。在第二阶段,渲染通过普通场景相机完成。此阶段可处理其他效果,例如补色着色。阴影贴图算法可用在片段着色器中,即靠近光源的片段绘制亮色,其他片段绘制阴影效果。

在第一阶段生成阴影贴图必要的信息,这些信息包含了片段到光源的距离信息。然后在光照空间重新映射片段,计算以光源为视点的深度,以及在阴影贴图纹理中的坐标。阴影贴图纹理以给定坐标系采样,并且片段深度可与采样结果进行对比。如果片段深度更远,则表示此片段在阴影中显示,否则此片段处在被光源照亮部分。

更多例子参考 Qt3D: Shadow Map QML Example.

InstancedRendering

实例化通过GPU绘制一个基本实例的多个副本,这些副本基于同一个实例变化。例如实例的位置、角度、颜色、材质属性、缩放比例等等参数的变化。Qt3D提供API访问QtQuickRepeater元素。那么,代理就是基本对象,而模型提供每一个实例的数据。因此一个带有网状的实体绘制过程将转换为对glDrawElements的调用,一个带有实例化组件的实体绘制过程将转换为对glDrawElementsInstanced的调用。

在将来的版本中,实例化渲染支持将会更多。

UniformBuffer Objects

UBO可通过绑定到OpenGL着色器程序来提交大批量绘制数据。UBO的典型用例如材质和光照参数集。

ConfigurableRenderer

为了让可充分配置的渲染器同时支持C++QMLAPIframegraph的概念诞生了。场景图形(scenegraph)和帧图形(framegraph)都是数据驱动的,两者的区别是,前者中的数据描述了绘制的内容,后者的数据描述了怎样绘制。

通过帧图形(framegraph),开发者可选择正向渲染器(z轴深度顺序渲染),也可选择延迟渲染器,例如控制什么时候渲染透明对象等等。具体选择何种渲染器是可配置的,并且可在程序运行时配置,不修改任何C++代码。开发者可通过实现自定义的渲染算法创建自己的帧图形(framegraph),作为Qt3D的扩展。

3DExtensions

除了在屏幕上渲染3D内容外,Qt3D还包含3D对象有关的如下特性:

  • 物理仿真

  • 碰撞检测

  • 3D方位声频

  • 刚体、骨骼、目标动画变换

  • 路径寻找和其他人工智能

  • 拾取

  • 粒子

  • 对象分裂

Performance

CPU核数越多,Qt3D的性能也会得到提升,现在的CPU都在通过增加核数而非提高时钟频率来提升性能。使用多核CPU可一定程度提升性能,许多任务间相互独立,可并行执行。例如,路径查找模块执行的动作和渲染器的渲染动作彼此间独立,可并发执行,获取渲染调试信息和统计信息时可单线执行。

Qt3D Architecture


Qt3D主要用于近实时对象仿真,同时在屏幕上渲染不同状态的对象。例子太空侵略者(TheSpace Invaders)包含如下对象:

  • 玩家控制的地面大炮

  • 地面

  • 防御块

  • 敌人的太空侵略船

  • 敌人的指挥飞碟

  • 敌人和玩家发射的子弹

传统的C++设计模式中,这些对象以继承关系的对象树类来描述。在对象树的各继承分支中可增加额外的功能和特性,例如:

  • 接收用户输入

  • 声音

  • 生存/死亡状态

  • 和其他对象的碰撞

  • 是否要绘制在屏幕上

太空侵略者的例子包含这些特征。然而,哪怕为一个简单的例子设计一个优雅的继承树都并不简单。

这种继承的设计方法和其他类似的设计方法都存在如下问题:

  • 深度和广度继承的等级难以理解、维护和扩展。

  • 继承分类在编译时就已固定。

  • 类继承树上的每一个层级只能基于一个单一的准则或主线来分类。

  • 多个类共有的功能将上升到更上层类中。

  • 无法预测开发者想要做什么。

扩展深度和广度继承树通常需要理解和认可原作者的分类方式。Qt3D是通过聚合而非继承的方式将功能赋予一个对象实例。为此,Qt3D实现了一个实体组建系统(ECS).

Usingan ECS

在一个ECS中,一个实体代表一个模拟的对象,但对象本身没有任何特定行为或特征。可以通过绑定实体组件增加ECS的行为。

在太空侵略者例子中,地面作为一个实体,包含一个附加的组件,此组件描述了实体需要渲染,使用哪种方式渲染。敌军的太空飞船是另一个实体,它的附加组件描述飞船的渲染、发出声音、碰撞、动态飞行、通过简单的人工智能控制飞行轨迹。

除了大炮没有人工智能组件外,玩家的大炮实体和敌军太空飞船实体两者的组件很相似。大炮有输入组件,用于帮助玩家移动大炮并发射子弹。

ECSBackend


这里有一个重要的概念——面向方面。所以在其中你看到很多Aspect字眼。这是因为我们将一个实体(Entity)分成很多组件(Component),其中有很多组件组合起来成为一个方面,剩下的组成另外一个方面。比如说Qt3D有核心方面、渲染方面、声音方面、输入方面、Quick渲染方面。它们被组成一个个库,根据用户的需求来链接。

例如,渲染方面,会查找实体相关的网状、材质和转换(如果需要)组件。如果渲染方面找到这类实体,渲染器知道怎样获取数据并更好的绘制它们。如果实体没有这些组件,渲染方面会忽略此实体。

Qt 3D通过聚合提供附加能力的组件新建自定义实体。Qt3D引擎通过方面的指定组件处理和更新实体。

例如,物理方面会查找许多碰撞探测组件,模拟块状物理、摩擦系数等特定属性相关的组件。可发出声音的实体则有一个声音相关的组件,组件也会指定何时发出哪种声音。

因为ECS使用的是聚合而非继承,因此可在运行时通过简单的增删组件改变对象的行为。

例如,为了在某个通电状态使玩家突然穿越墙面,可在通电状态结束前临时移除实体的碰撞探测组件。但是我们并不需要实现特殊的开关子类例如PlayerWhoRunsThroughWalls

Qt3D ECS Implementation

Qt 3D通过简单的类继承实现ECSQt3D基类是Qt3DCore::QNode,它是QObject的子类。当属性改变时,Qt3DCore::QNode会自动发出属性改变的通知,同时会在子线程中处理属性,Qt3DCore::QNode也会简化用户界面线程和属性相关子线程的数据传输。

一般来说,Qt3DCore::QNode的子类提供了对数据的额外支持,此功能用于组件中。例如渲染实体集时,QShaderProgram类指定使用GLSL代码。

Qt3D中的组件继承自Qt3DCore::QComponent,同时会为相关方面添加需要的属性。例如,渲染方面会使用网状组件检索每个应该发送到OpenGL管线的顶点数据。

最后,Qt3DCore::QEntity是一个能够聚合0个或多个Qt3DCore::QComponent实体的对象。

ExtendingQt 3D

不论添加Qt3D的功能作为Qt的一部分,还是作为应用的一部分,多线程后端一般由如下任务组成:

确定和实现任何需要的组件和支持的数据。

使用QML引擎注册组件(仅在使用QMLAPI)

子类化QAbstractAspect并实现子系统功能。

Qt3D Task-Based Engine

Qt3D中,在一个任务集的每一帧中都会询问使用哪方面执行。为了提升性能,调度器根据所有配置好的CPU核数分发任务。

Qt3D's Aspects

Qt3D默认会提供Qt3DRenderQt3DInput方面。这些方面会提供组件和其他支持的类,此类模块在文档中有说明。将来的Qt3D版本,额外的方面将会提供更多能力。


Summary

Qt 3DQt5.5.0中引入的新模块,目前处在技术预览状态。Qt3D模块在3D可视化、游戏和仿真领域应该有广阔的应用前景,能够使开发者比直接使用OpenGL接口更加快速和容易实现需要的特性。目前Qt3D相关的文档和支持还不是很全面,在未来的版本中会不断完善。

  • 0
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
This directory contains the Qt3D project for Qt5: * Qt3D QML bindings and * Qt3D C++ APIs Building Qt3D ================== Qt5 is a rapidly changing bleeding edge environment. This branch is our initial support for it and thus is also rapidly changing and bleeding edge. This branch is experimental, and unsupported. This information is provided for advanced use only. No guarantees about API stability or even if this works at all are supplied, use at your own risk. First fetch the Qt5 source tree and Qt3D master branch: cd ~/depot git clone ssh://codereview.qt-project.org:29418/qt/qt5.git cd qt5 ./init-repository --codereview-username \ --module-subset=qtbase,qtsvg,qtdeclarative,qttools,qtxmlpatterns,qtdoc,qlalr,qtrepotools,qtqa,qtlocation,qt3d git submodule foreach "git fetch gerrit && git reset --hard gerrit/master" cd qt3d scp -p -P 29418 codereview.qt-project.org:hooks/commit-msg .git/hooks/ git fetch gerrit git checkout --track -b master gerrit/master If you are reading this file then somehow you probably already got this far anyway. Now build Qt5, which will also build Qt3D as a module: cd ~/build mkdir qt5 cd qt5 ~/depot/qt5/configure -developer-build -opensource -confirm-license -no-webkit -no-phonon -nomake tests \ -nomake examples -declarative -opengl -svg && make -j 4 What's in Qt3D ================== Directory structure: src/threed/ This is the main library of the Qt3D project, containing abstractions for cross-platform GL, shaders, lighting models, and so on. src/plugins/ Scene format loading plugins. src/imports/ QML import plugins. util/ Various utilities that are useful when working with Qt3D. examples/ Some examples of using Qt3D QML bindings and Qt3D C++ API. demos/ Some more complex demos of using Qt3D QML bindings and Qt3D C++ API. tests/auto/qml3d/ Unit tests for the QML bindings. tests/auto/threed/ Unit tests for the C++ API doc/ Documentation. devices/symbian/ Symbian deployment file Documentation ============= The documentation can be generated with "make docs". It will be placed into "doc/html" in the build directory. Packages ======== This section is only for those developing Qt3D. Read on to discover how the building of packages works. This section is also important if you want to change how the structure of the Qt3D pro files work. To build Qt3D, run: qmake && make The .pro files will cause the toolchain to place the libraries, QML files and meshes of Qt3D directly into place, as part of the compile process. The files go into the bin/ directory, and the executables can be run directly from there. If you are doing a developer build, plugins will be installed in such a way that Qt will find them. After building the tree the install step is invoked using the INSTALL_ROOT environment export to cause the installation rules to place all the files into a sandboxed install tree, ready for packaging: INSTALL_ROOT=tmp make install Examples ======== Some examples require assimp library to parse the content. Go to http://assimp.sourceforge.net/ and build and install the assimp library. Then configure Qt3D to include assimp and run qmake && make.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值