v5.14.0
使用QML 3D时需要 import Qt3D.Core 2.14
V6以上的版本已经发布,所以有很多module会发生变化,主要有核心module、输入、逻辑、渲染、动画和扩展module,以及2D/3D场景模块
| 类名 | 能力 |
| 为绘制3D数据提供了在2D场景中显示的窗口 | |
| OrbitCameraController | 按照轨道路线来控制场景相机 |
| QAbstractAnimation | 3D动画的顶层root类,派生的动画类提供了动画效果能力 |
3d效果中离不开动画,所以要想学好3d部分,需要将动画部分也掌握。然后再从最基础的3d理论知识入门
官方给出了很多例子,可以根据官方demo进行由浅入深的学习。地址在source code中:SourceCode Root Path/qt3d/
此外,网络上还提供了不少入门的demo,从较小的纬度(基础的加载3d资源、鼠标处理等操作)提供了演示操作,下面是收集来的各种操作集合。
1、加载3D模型资源+将.obj文件转换成.mesh类型文件
- import QtQuick 2.15
- import QtQuick.Window 2.15
- import QtQuick3D 1.15
-
- Window {
- width: 640
- height: 480
- visible: true
- title: qsTr("Hello World")
-
- View3D {
- id: view3D
- anchors.fill: parent
- environment: sceneEnvironment
- SceneEnvironment {
- id: sceneEnvironment
- antialiasingQuality: SceneEnvironment.High
- antialiasingMode: SceneEnvironment.MSAA
- }
-
- Node {
- id: node
- DirectionalLight {
- id: directionalLight
- }
-
- PerspectiveCamera {
- id: camera
- z: 15
- }
-
- Model {
- id: cubeModel
- source: "test.mesh"
- DefaultMaterial {
- id: cubeMaterial
- diffuseColor: "#4aee45"
- }
- materials: cubeMaterial
- }
- }
- }
- }
- import QtQuick 2.15
- import QtQuick.Window 2.15
- import QtQuick3D 1.15
-
- Window {
- width: 640
- height: 480
- visible: true
- title: qsTr("Hello World")
-
- View3D {
- id: view3D
- anchors.fill: parent
- environment: sceneEnvironment
- SceneEnvironment {
- id: sceneEnvironment
- antialiasingQuality: SceneEnvironment.High
- antialiasingMode: SceneEnvironment.MSAA
- }
-
- MouseArea{
- id:mouse
- anchors.fill: parent
- property int cx: 0
- property int cy: 0
- onWheel: {
- if(wheel.angleDelta.y>0)
- camera.z = camera.z+5
- else
- camera.z = camera.z-5
- }
- onPressed: {
- cx = mouse.x
- cy = mouse.y
- }
-
- onPositionChanged: {
- var intervalX = mouse.x-cx
- var intervalY = mouse.y-cy
- cameraNode.eulerRotation.y = intervalX+cameraNode.eulerRotation.y
- cameraNode.eulerRotation.x = cameraNode.eulerRotation.x-intervalY
- cx = mouse.x
- cy = mouse.y
- }
- }
- Node {
- id: node
- DirectionalLight {
- id: directionalLight
- }
-
- Model {
- id: cubeModel
- source: "test.mesh"
- DefaultMaterial {
- id: cubeMaterial
- diffuseColor: "#4aee45"
- }
- materials: cubeMaterial
- }
- }
-
- Node{
- id:cameraNode
- PerspectiveCamera {
- id: camera
- z: 15
- }
- }
- }
- }
- import QtQuick 2.15
- import QtQuick.Window 2.15
- import QtQuick3D 1.15
-
- Window {
- width: 640
- height: 480
- visible: true
- title: qsTr("Hello World")
-
- View3D {
- id: view3D
- anchors.fill: parent
- environment: sceneEnvironment
- SceneEnvironment {
- id: sceneEnvironment
- antialiasingQuality: SceneEnvironment.High
- antialiasingMode: SceneEnvironment.MSAA
- }
-
- MouseArea{
- id:mouse
- anchors.fill: parent
- property int cx: 0
- property int cy: 0
- onWheel: {
- if(wheel.angleDelta.y>0)
- camera.z = camera.z+5
- else
- camera.z = camera.z-5
- }
- onPressed: {
- cx = mouse.x
- cy = mouse.y
- }
-
- onPositionChanged: {
- var intervalX = mouse.x-cx
- var intervalY = mouse.y-cy
- cameraNode.eulerRotation.y = intervalX+cameraNode.eulerRotation.y
- cameraNode.eulerRotation.x = cameraNode.eulerRotation.x-intervalY
- cx = mouse.x
- cy = mouse.y
- }
- }
- Node {
- id: node
- DirectionalLight {
- id: directionalLight
- }
-
- Model {
- id: cubeModel
- source: "test.mesh"
-
- materials: PrincipledMaterial {
- id: cubeMaterial
- baseColor: "#e9d805"
- roughness: 0.4
- metalness: 0.8
- }
- }
- }
-
- Node{
- id:cameraNode
- PerspectiveCamera {
- id: camera
- z: 15
- }
- }
- }
- }
- import QtQuick 2.15
- import QtQuick.Window 2.15
- import QtQuick3D 1.15
-
- Window {
- width: 640
- height: 480
- visible: true
- title: qsTr("Hello Qt Quick 3D")
-
- View3D {
- id: view3D
- anchors.fill: parent
- environment: sceneEnvironment
- SceneEnvironment {
- id: sceneEnvironment
- antialiasingQuality: SceneEnvironment.High
- antialiasingMode: SceneEnvironment.MSAA
- }
-
- Node {
- id: node
- DirectionalLight {
- id: directionalLight
- }
-
- Model {
- id: cubeModel
- source: "test.mesh"
- DefaultMaterial {
- id: cubeMaterial
- diffuseColor: "#4aee45"
- }
- materials: cubeMaterial
- }
- }
-
- Node{
- id:cameraNode
-
- PerspectiveCamera {
- id: camera
- z: 15
- }
-
- NumberAnimation {
- id:camerAnimation
- target: cameraNode
- property: "eulerRotation.y"
- duration: 5000
- from: 0
- to: -360
- loops: Animation.Infinite
- running: true
- }
- }
- }
- }
如果需要自定义背景图片时,需要设置View3D的背景色为透明,方法在上面链接中
- import QtQuick 2.15
- import QtQuick.Window 2.15
- import QtQuick3D 1.15
-
- Window {
- width: 480
- height: 450
- visible: true
- title: qsTr("Hello Qt Quick 3D")
- color: "#00192e"
-
- Image{
- opacity: 0.3
- anchors.fill: parent
- source: "qrc:/bg1.png"
- fillMode: Image.PreserveAspectCrop
- }
-
- View3D {
- id: view3D
- anchors.fill: parent
- environment: SceneEnvironment {
- id: sceneEnvironment
- //需要设置3D视图背景透明
- backgroundMode: SceneEnvironment.Transparent
- clearColor: "transparent"
- antialiasingQuality: SceneEnvironment.High
- antialiasingMode: SceneEnvironment.MSAA
- }
-
-
- MouseArea{
- id:mouse
- anchors.fill: parent
- property int cx: 0
- property int cy: 0
- onWheel: {
- if(wheel.angleDelta.y>0)
- cameraPerspective.z = cameraPerspective.z+5
- else
- cameraPerspective.z = cameraPerspective.z-5
- }
- onPressed: {
- camerAnimation.pause()
- cx = mouse.x
- cy = mouse.y
- }
- onReleased: {
- camerAnimation.resume()
- }
- onPositionChanged: {
- var intervalX = mouse.x-cx
- var intervalY = mouse.y-cy
- cameraNode.eulerRotation.y = intervalX+cameraNode.eulerRotation.y
- cameraNode.eulerRotation.x = cameraNode.eulerRotation.x-intervalY
- cx = mouse.x
- cy = mouse.y
-
- }
- }
-
- Node {
- id: scene
-
- DirectionalLight {
- x: 56
- eulerRotation.y: 90
-
- ambientColor: "#1c1a17"
- brightness: 163
- }
- Node {
- id: rootNode
- scale:Qt.vector3d(0.1,0.1,0.1)
- Node {
- x: 12.4775
- y: 36.2141
- z: 10.5153
- eulerRotation.x: 180
- eulerRotation.y: 32.0597
- eulerRotation.z: -180
-
- Model {
- x: 121.16
- y: -17.21
- z: 86.29
- eulerRotation.x: 180
- eulerRotation.y: -32.0597
- eulerRotation.z: -180
- source: "meshes/Plane.mesh"
-
- materials: PrincipledMaterial {
- baseColor: "#a0a2a3"
- roughness: 0.6
- metalness: 0.5
-
- }
- }
- }
-
-
- PointLight {
- x: 80.1709
- y: 382.888
- z: -150.021
- eulerRotation.x: -69.997
- eulerRotation.y: 59.9021
- eulerRotation.z: -180
- color: "#fffff5e1"
- }
-
- PointLight {
- x: -305.432
- y: 199.762
- z: 163.037
- eulerRotation.x: 173
- eulerRotation.y: -59.9035
- color: "#ffecf9ff"
- }
-
- PointLight {
- x: 238.189
- y: 380.379
- z: 252.482
- eulerRotation.x: 138.592
- eulerRotation.y: 36.109
- color: "#ff3b5966"
- }
- }
-
- Node{
- id:cameraNode
- eulerRotation.x: -20
- eulerRotation.y: 120
- PerspectiveCamera {
- id: cameraPerspective
- y: 5
- clipNear: 0.1
- fieldOfView: 50
- z:90
- clipFar: 800
- }
- NumberAnimation {
- id:camerAnimation
- target: cameraNode
- property: "eulerRotation.y"
- duration: 5000
- from: 0
- to: 360
- loops: Animation.Infinite
- running: true
- }
- }
-
-
-
- }
-
- Text {
- text: qsTr("鼠标左键:旋转;鼠标滚轮:缩放")
- anchors.right: parent.right
- anchors.bottom: parent.bottom
- font.pointSize: 12
- font.bold: true
- anchors.rightMargin: 10
- anchors.bottomMargin: 10
- font.family: "微软雅黑"
- color:"ghostwhite"
- }
- }
- }
两个坐标,连接起来就是北面墙。什么意思?想象一下,其中一个坐标是东北方的下墙角,以墙角为原点,往南是X轴;往上是Y轴;往西是Z轴。另一个坐标是西北方的下墙角,还是以墙角为原点,往南是X轴;往上是Y轴;往东是Z轴。两个坐标系相互延伸、连接起来就是一面北墙。
半握右手,大拇指朝上,从手背到四指的延伸方向就是坐标轴旋转方向