2.qml 3D-View3D类学习

本章我们来学习View3D类。

View3D是用来渲染3D场景并显示在2D平面的类,并且该类可以放在QML2D下继承于Item子类的任何场景中,比如将View3D放在Rectangle中:

cs 复制代码
Rectangle {
        width: 200 
        height: 200
        color: "red"
        View3D {    
                anchors.fill: parent   
                anchors.margins: 40
                // ... ...
        }
}

效果如下所示:

View3D是用来渲染3D场景的,所以我们可以通过environment属性来设置环境参数,比如设置3D背景色、抗锯齿、天空盒等等,比如设置:

cs 复制代码
environment: SceneEnvironment {
            clearColor: "red"            // 设置背景色为红色
            backgroundMode: SceneEnvironment.Color   // 设置背景模式为color,也可以设置为天空盒、透明等等
            antialiasingMode: SceneEnvironment.MSAA  // 抗锯齿模式
            antialiasingQuality: SceneEnvironment.High  //  抗锯齿质量
  }

如果我们要在场景中显示2D类(必须是Item子类),可以通过Node类实现、比如我们要在View3D中显示一个Text:

cs 复制代码
import QtQuick
import QtQuick.Window
import QtQuick3D
import QtQuick3D.Helpers
Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    View3D {
        anchors.fill: parent
        environment: SceneEnvironment {
            clearColor: "#F1F1F1"
            backgroundMode: SceneEnvironment.Color
            antialiasingMode: SceneEnvironment.MSAA
            antialiasingQuality: SceneEnvironment.High
        }

        PerspectiveCamera {
            id: camera
            position: Qt.vector3d(0, 0, 440)
        }

        Node {
            Rectangle {
                width: 400
                height: 400
                x: -width/2
                y: -height/2
                color: "#77202020"
                radius: 10
                border.width: 2
                border.color: "#77f0f0f0"
                Text {
                    anchors.centerIn: parent
                    font.pixelSize: 20
                    color: "#FFF"
                    font.family: "Microsoft Yahei"
                    style: Text.Raised
                    styleColor: "#111"
                    text: "QML3D学习 by诺谦"
                }
            }
        } 
    } 
}

效果如下所示:

这里我们使用了PerspectiveCamera 相机,要让View3D显示出来则必须需要一个继承于Camera类的相机,否则View3D无法知道我们要从哪个角度去展示3D场景。

我们设置了摄像机的positionQt.vector3d(0, 0, 440)、只设置了z为440,而欧拉角度默认是0,所以可以看出摄像机的方向默认是从Z方向照射XY方向的。

假如我们设置为:

cs 复制代码
PerspectiveCamera {
            id: camera
            position: Qt.vector3d(0, -200, 440)    // 摄像机Y方向后退200
            eulerRotation.x: 30                    // 绕x正方向旋转30°
 }

效果如下所示:

而我们设置的Rectangle的x和y为宽高的负一半,这是为了让Rectangle在原点居中显示,除此之外,Node还可以组合式显示,比如:

cs 复制代码
Node {
    Rectangle {
        width: 400
        height: 400
        x: -width/2
        y: -height/2
        color: "#77202020"
    }
    Rectangle {
        width: 400
        height: 400
        x: 0
        y: 0
        color: "#77202020"
    } 	
}

效果如下所示:


其中Node类介绍如下所示:

如上图可以看到,Node类的子类非常多,比如Model类(显示3D模型)、ParticleSystem3D粒子系统类、Light光照类 等等。

所以Node类非常重要,下章我们便来来学习Node类,再来学习其它类就会非常的方便快捷。

View3D的其它相关属性和方法介绍

  • **importScene :**设置公共的Node,比如有多个View3D,其内容都是相同的Node,只是相机位置不一致而已,具体参考示例(View3D Example),注意:该属性只能设置一次,后续更改将无效。
  • camera : QtQuick3D::Camera,指定用哪个相机来显示
  • **environment :**QtQuick3D::SceneEnvironment,设置渲染场景,比如背景色
  • importScene :QtQuick3D::Node,设置公共的Node,比如有多个View3D,其内容都是相同的Node,只是相机位置不一致而已,具体参考示例(View3D Example),注意:该属性只能设置一次,后续更改将无效。
  • **renderFormat :**enumeration, 设置渲染纹理的格式,默认为ShaderEffectSource.RGBA8
  • renderMode : enumeration,渲染模式,默认为View3D.Offscreen,只有当某些GOU硬件不支持时,才会去更改渲染模式。
  • **renderStats :**QtQuick3D::RenderStats,只读属性,统计信息,比如fps实时刷新率,frameTime,renderTime,syncTime, 和maxFrameTime等等
  • scene : QtQuick3D::Node, 只读属性, 保存View3D场景的根节点。

方法如下所示:

  • **vector3d mapFrom3DScene(vector3d scenePos) :**将scenePos场景空间位置(3D)转换到视图平面位置(2D)
  • **vector3d mapTo3DScene(vector3d viewPos) :**将viewPos视图平面位置(2D)转换到场景空间位置(3D)
  • **PickResult pick(float x, float y) :**此方法将从视图坐标xy位置"射"一条光线到3D场景中,并返回与射线最近交叉的物体信息。例如,可以使用鼠标坐标来调用它来查找鼠标光标下的对象.
  • **List<PickResult> pickAll(float x, float y) :**和pick函数类似,不过是从视图坐标xy位置"射"一条光线到3D场景中,并返回与射线所有交叉的物体信息列表并从近到远进行排序
  • PickResult rayPick(vector3d origin, vector3d direction) : 获取从场景空间位置origin,发出一个direction方向的射线,并返回与射线最近交叉的物体信息,例如,在判断射击子弹时是否有碰撞
  • **List<PickResult> rayPickAll(vector3d origin, vector3d direction):**和rayPick函数类似,不过获取的是一个所有交叉的列表

而PickResult 类常用参数如下所示:

  • distance : float, 拾取距离,也就是射出光线的原点与交叉点的距离
  • **instanceIndex :**int,当拾取命中实例模型的实例时,此属性保存实例表中的索引,如果该模型不是由多个子模块组成,那么始终返回0
  • **normal :**vector3d,保存局部坐标空间中被击中的面的法线。
  • objectHit : Model,保存被选中的模型对象,我们可以通过!=null来判断是否有选中对象
  • **position :**vector3d,保存拾取命中时,在3D空间中的场景位置

接下来我们便来实现一个点击3D物体变色的示例。

由于点击只有对3D模型才有效果(比如对光无法进行点击),所以我们需要使用Model类,Model类需要在学了Node类后再详解,所以本章只简单使用,示例如下所示:

cs 复制代码
import QtQuick
import QtQuick.Window
import QtQuick3D
Window {
    width: 640
    height: 480
    visible: true
    title: qsTr("Hello World")
    View3D {
        id: _view
        anchors.fill: parent

        environment: SceneEnvironment {
            clearColor: "#F1F1F1"
            backgroundMode: SceneEnvironment.Color
            antialiasingMode: SceneEnvironment.MSAA
            antialiasingQuality: SceneEnvironment.High
        }
        camera: camera
        PerspectiveCamera {
            id: camera
            position: Qt.vector3d(0, -900, 800)
            eulerRotation.x: 45
        }

        MouseArea {
            anchors.fill: parent
            onClicked: (mouse)=> {
                let ret = _view.pick(mouse.x, mouse.y)
                if(ret.objectHit != null)
                    ret.objectHit.materials[0].diffuseColor =
                           Qt.rgba(Math.random(),Math.random(), Math.random(), 1.0)

            }
        }

        DirectionalLight {
           eulerRotation: Qt.vector3d(0, 0, 0)
           castsShadow: true
           brightness: 3
        }

        Model {
            id: _sphere
            source: "#Sphere"
            z: 300
            pickable: true
            scale: Qt.vector3d(2, 2, 2)
            materials: DefaultMaterial {
                diffuseColor: Qt.rgba(0.6, 0.5, 0.2, 1.0)
            }
        }


        Model {
            source: "#Rectangle"
            pickable: true
            scale: Qt.vector3d(10, 10, 1)
            materials: DefaultMaterial {
                diffuseColor: Qt.rgba(0.7, 0.2, 0.2, 1.0)
            }
        }
    }

}

运行效果如下所示:

未完待续

相关推荐
superman超哥29 分钟前
04 深入 Oracle 并发世界:MVCC、锁、闩锁、事务隔离与并发性能优化的探索
数据库·oracle·性能优化·dba
engchina1 小时前
Neo4j 和 Python 初学者指南:如何使用可选关系匹配优化 Cypher 查询
数据库·python·neo4j
engchina1 小时前
使用 Cypher 查询语言在 Neo4j 中查找最短路径
数据库·neo4j
尘浮生1 小时前
Java项目实战II基于Spring Boot的光影视频平台(开发文档+数据库+源码)
java·开发语言·数据库·spring boot·后端·maven·intellij-idea
威哥爱编程1 小时前
SQL Server 数据太多如何优化
数据库·sql·sqlserver
小华同学ai1 小时前
AJ-Report:一款开源且非常强大的数据可视化大屏和报表工具
数据库·信息可视化·开源
Acrelhuang2 小时前
安科瑞5G基站直流叠光监控系统-安科瑞黄安南
大数据·数据库·数据仓库·物联网
十叶知秋3 小时前
【jmeter】jmeter的线程组功能的详细介绍
数据库·jmeter·性能测试
瓜牛_gn4 小时前
mysql特性
数据库·mysql
奶糖趣多多5 小时前
Redis知识点
数据库·redis·缓存