QQuick3D-Camera的介绍
QQuick3D-Camera的介绍
Camera的概述
-
Camera类继承于 Node;Camera定义了怎样将一个3D场景(Scene)投影到2D的表面上;一个场景至少需要一个Camera来可视化其内容。
-
Camera 可以像场景中任何节点一样,被定位和旋转;Camera节点的位置和方向决定了Camera在场景中的位置及其朝向;Camera的默认方向是,其前向矢量指向负Z轴,其上向矢量指向正Y轴。
-
QQuick3D提供以下几种类型相机:
** PerspectiveCamera**:透视投影相机,具有近大远小特点
OrthographicCamera:正交投影相机,提供了一种平截头体线条平行的相机,使物体的感知比例不受其与相机距离的影响。这种相机的典型用例是CAD(计算机辅助设计)应用程序和制图
FrustumCamera:
CustomCamera : 自定义相机,由用户自定义 投影矩阵 -
属性frustumCullingEnabled : bool:当此属性为真时,相机平截头体之外的对象将被剔除,这意味着它们不会传递给渲染器。默认情况下,此属性设置为false。对于所有或大多数对象都在相机平截头体内的场景,平截头体剔除是一种不必要的性能开销。但对于大部分位于相机视野之外的复杂场景,启用平截头体剔除可能会提高性能
-
属性lookAtNode : Node: Node 非空时,当lookAtNode 观察节点位置发生变化时,相机的位置会跟随发生变化;默认值为null
-
方法vector3d lookAt(vector3d scenePos):设置摄影机的旋转值,使其指向scenePos
-
方法vector3d lookAt(QtQuick3D::Node node):设置摄影机的旋转值,使其指向节点
-
方法vector3d mapFromViewport(vector3d viewportPos):将viewportPos从视口空间(viewPort Space)(2D)转换为全局场景空间(3D)。viewportPos的x和y值必须归一化,视口的左上角为[0,0],右下角为[1,1]。z值被解释为距截头体近剪裁平面的距离(clipNear)。如果viewportPos无法成功映射到场景中的某个位置,则返回[0,0,0]的位置。
-
方法vector3d mapToViewport(vector3d scenePos):将scenePos从全局场景空间(3D)转换到视口空间(2D)。返回的位置被归一化,视口的左上角为[0,0],右下角为[1,1]。返回的z值将包含从截头体的近剪裁平面(clipANear)到场景坐标中scenePos的距离。如果距离为负,则该点位于相机后面。如果scenePos无法成功映射到视口中的某个位置,则返回[0,0,0]的位置
Camera的实例代码
注意 代码中 “teapot.mesh” 这个网格,Qt 官方实例中有提供。
import QtQuick
import QtQuick.Controls
import QtQuick.Layouts
import QtQuick3D
//摄像机Demo
Item {
id: root
//场景需要 Model(mesh + Material), Light, Camera, 3个元素
Node{
id: rootSceneNode //3D场景的根节点
//平行光: 光源从无线远地方发射,类似于生活中太阳;平行光具有无限的范围,不会衰减;如果启用castsShadow,阴影将平行于灯光方向;
//平行光实际上没有位置,因此移动它没有任何效果。光将始终沿光的Z轴方向发射。沿X或Y轴旋转灯光将改变发光方向。
DirectionalLight {
ambientColor: Qt.rgba(0.5, 0.5, 0.5, 1.0)
brightness: 1.0
eulerRotation.x: -25
}
Model {
//Model 需要网格 + 材质
source: "qrc:/qt/qml/text/3DDemo/teapot.mesh"
y: -100
scale: Qt.vector3d(50, 50, 50)
materials: [
PrincipledMaterial {
baseColor: "#41cd52"
metalness: 0.0
roughness: 0.1
opacity: 1.0
}
]
//沿着Y轴旋转,在xz所在平台旋转
// PropertyAnimation on eulerRotation.y {
// loops: Animation.Infinite
// duration: 5000
// to: 0
// from: -360
// }
}
//
Node {
//使用节点给摄像机设置动画。
//Camera 做为Node 的子节点,可以通过Node节点的属性来定义相机的位置、旋转 之类属性;也会继承父节点的变换
//透视投影:主要涉及 近平面(clipNear),远平面(clipFar),视野角(fiedOfView)
id: idCamPNode
PerspectiveCamera {
id: cameraPerspectiveOne
z: 600
// onSceneRotationChanged: {
// console.log("onSceneRotationChanged = ",cameraPerspectiveOne.sceneRotation);
// }
// onScenePositionChanged: {
// console.log("onScenePositionChanged = ",cameraPerspectiveOne.scenePosition);
// }
// onSceneTransformChanged: {
// console.log("onSceneTransformChanged");
// }
}
//
PropertyAnimation on eulerRotation.y {
loops: Animation.Infinite
duration: 5000
to: -360
from: 0
}
}
}
View3D{
id:idView3D
anchors.fill: parent
importScene: rootSceneNode
camera: cameraPerspectiveOne
MouseArea{
anchors.fill: parent
onClicked:(mouse)=> {
var viewPos = Qt.vector3d(mouse.x /parent.width,mouse.y/parent.height,0);
//同样的viewPos 因为Camera的位置在变化,造成映射到scene中值不一致
var scenePos = cameraPerspectiveOne.mapFromViewport(viewPos);
console.log("scenePos = ",scenePos, " viewPos = ",mouse.x,mouse.y);
}
}
}
}