main.cpp
//演示使用 PBR 材料的 QML 应用程序。
//Pbr-Materials 演示了如何使用 Qt 3D 材料系统。
#include <Qt3DQuickExtras/qt3dquickwindow.h>
#include <Qt3DQuick/QQmlAspectEngine>
#include <QGuiApplication>
#include <QQmlEngine>
#include <QQmlContext>
int main(int argc, char* argv[])
{
QGuiApplication app(argc, argv);
Qt3DExtras::Quick::Qt3DQuickWindow view;
将窗口作为上下文属性公开,以便我们可以设置纵横比
view.engine()->qmlEngine()->rootContext()->setContextProperty("_window", &view);
view.setSource(QUrl("qrc:/main.qml"));
view.show();
return app.exec();
}
main.qml
import QtQuick 2.1
import Qt3D.Core 2.0
import Qt3D.Render 2.9
import Qt3D.Input 2.0
import Qt3D.Extras 2.15
Entity {
id: root
objectName: "root"
// 使用 ForwardRenderer.qml 中指定的渲染器配置
// 并从 mainCamera 渲染
components: [
RenderSettings {
activeFrameGraph: ForwardRenderer {
camera: mainCamera
}
},
// 事件源将由 Qt3DQuickWindow 设置
InputSettings { }
]
BasicCamera {
id: mainCamera
position: Qt.vector3d( -5.17253, 2.95727, 6.65948 )
viewCenter: Qt.vector3d( 6.73978, -2.50545, -10.6525 )
}
//FirstPersonCameraController 允许从第一人称视角控制场景相机
FirstPersonCameraController { camera: mainCamera }
Lights { }
Entity {
components: [
PointLight {
enabled: parent.enabled
color: "black"
intensity: 0
},
EnvironmentLight {
enabled: parent.enabled
//保存当前环境辐照度贴图纹理。
irradiance: TextureLoader {
source: "qrc:/assets/cubemaps/default/default_irradiance.dds"
wrapMode {
x: WrapMode.ClampToEdge
y: WrapMode.ClampToEdge
}
//此属性确定是否为本身不提供 mipmap 级别的纹理生成 mipmap。
//与没有它们的渲染相比,使用 mipmap 和 mip 过滤可以在远距离查看纹理时提供更好的视觉质量,
//但可能会降低性能(在初始化图像和渲染期间)。
generateMipMaps: false
}
//保存当前环境高光贴图纹理。
//默认情况下,环境镜面反射纹理为空。
//注意:此属性的确切含义和用途取决于材料实现。
specular: TextureLoader {
source: "qrc:/assets/cubemaps/default/default_specular.dds"
wrapMode {
x: WrapMode.ClampToEdge
y: WrapMode.ClampToEdge
}
generateMipMaps: false
}
}
]
}
Entity {
id: floor
components: [
Mesh {
source: "qrc:/assets/obj/plane-10x10.obj"
},
//此材质使用具有单一渲染通道方法的效果并执行每个片段照明。
//为 OpenGL 3 和 OpenGL ES 3 提供了技术
MetalRoughMaterial {
//保持材料的当前基色。 这可以是纯色值或纹理。 默认情况下,此属性的值为“灰色”。
baseColor: TextureLoader {
source: "qrc:/assets/textures/ceramic_small_diamond/ceramic_small_diamond_basecolor.png"
format: Texture.SRGB8_Alpha8
generateMipMaps: true
}
//将材料的当前金属度级别保存为
//0(纯介电性,默认值)和 1(纯金属性)之间的值
//这可以是普通的统一值或纹理。
//默认情况下,此属性的值为 0。
metalness: TextureLoader { source: "qrc:/assets/textures/ceramic_small_diamond/ceramic_small_diamond_metallic.png"; generateMipMaps: true }
//保持材料的当前粗糙度级别。
//这可以是普通的统一值或纹理。 默认情况下,此属性的值为 0。
roughness: TextureLoader { source: "qrc:/assets/textures/ceramic_small_diamond/ceramic_small_diamond_roughness.png"; generateMipMaps: true }
//保存材质的当前法线贴图纹理。
//这只能是纹理,否则将被忽略。 默认情况下未设置此地图。
normal: TextureLoader { source: "qrc:/assets/textures/ceramic_small_diamond/ceramic_small_diamond_normal.png"; generateMipMaps: true }
//保存材质的当前环境光遮挡贴图纹理。
//这只能是纹理,否则将被忽略。 默认情况下未设置此地图。
ambientOcclusion: TextureLoader { source: "qrc:/assets/textures/ceramic_small_diamond/ceramic_small_diamond_ambient_occlusion.png" }
}
]
}
TrefoilKnot {
id: trefoilKnot
y: 1.5
z: -2
scale: 0.2
//SequentialAnimation 和 ParallelAnimation 类型允许多个动画一起运行。
//SequentialAnimation 中定义的动画一个接一个运行,而 ParallelAnimation 中定义的动画同时运行。
//以下动画并行运行两个数字动画。
//通过同时为其 x 和 y 属性设置动画,矩形移动到 (50,50)。
/*
import QtQuick 2.0
Rectangle
{
id:rect
width:100;
height:100
color:"red"
ParallelAnimal
{
runnnig:true
NumberAnimation{target:rect;property:"x";to:50;duration:1000}
NumberAnimation{target:rect;property:"y";to:50;duration:1000}
}
}
*/
ParallelAnimation {
//此属性保存动画应播放的次数。
//默认情况下,loops 为 1:动画将播放一次然后停止。
//如果设置为 Animation.Infinite,动画将不断重复
//直到被明确停止 - 通过将 running 属性设置为 false,或通过调用 stop() 方法。
//在以下示例中,矩形将无限旋转。
/*
Rectangle
{
width:100;height:100;color:"green"
RotationAnimation on rotation
{
loops:Animation.Infinite
from:0
to:360
}
}
*/
loops: Animation.Infinite
//此属性保存动画当前是否正在运行。
//可以设置 running 属性以声明性地控制动画是否正在运行。
//下面的示例将在按下 MouseArea 时为矩形设置动画。
/*
Rectangle
{
width:100; height:100
NumberAnimation on x
{
running:myMouse.pressed
from: 0;to:100
}
MouseArea{id:myMouse}
}
*/
//同样,可以读取 running 属性以确定动画是否正在运行。
//在以下示例中,文本项将指示动画是否正在运行。
/*
NumberAnimation{id:myAnimation}
Text{text:myAnimation.running?"Animation is running":"Animation is not running"}
*/
//动画也可以使用 start() 和 stop() 方法从 JavaScript 强制启动和停止。
//默认情况下,动画不运行。
//但是,当动画被分配给属性时,作为使用 on 语法的属性值源,它们默认设置为运行。
running: true
//NumberAnimation 是一个专门的 PropertyAnimation,
//它定义了当数值改变时要应用的动画。
//这是一个应用于 Rectangle 的 x 属性的 NumberAnimation 作为属性值源。
//它在 1000 毫秒内将 x 值从其当前值动画化为 50:
/*
import QtQuick 2.0
Rectangle
{
width:100;height:100
color:"red"
NumberAnimation on x {to:50;duration:1000}
}
*/
//与任何其他动画类型一样,
//NumberAnimation 可以通过多种方式应用,包括过渡、行为和属性值源。
//Qt Quick 文档中的动画和过渡展示了多种创建动画的方法。
//请注意,如果 NumberAnimation 正在跟踪的数值发生不规则变化,则它可能无法平滑地设置动画。
//如果是这种情况,请改用 SmoothedAnimation。
NumberAnimation {
target: trefoilKnot
property: "theta"
from: 0; to: 360
duration: 5000
}
NumberAnimation {
target: trefoilKnot
property: "phi"
from: 0; to: 360
duration: 5000
}
}
}
Mesh {
id: matSphere
source: "qrc:/assets/obj/material-sphere.obj"
}
Entity {
id: sphere1
components: [
matSphere1Transform,
matSphere,
matSphere1Material
]
Transform {
id: matSphere1Transform
translation: Qt.vector3d(-3, 0, 0)
rotationY: -90
}
//此材质使用具有单一渲染通道方法的效果并执行每个片段照明
//为 OpenGL 3 和 OpenGL ES 3 提供了技术。
MetalRoughMaterial {
id: matSphere1Material
//保持材料的当前基色。 这可以是纯色值或纹理。
//默认情况下,此属性的值为“灰色”。
baseColor: TextureLoader {
source: "qrc:/assets/textures/aluminium_random_brushed/aluminium_random_brushed_basecolor.png"
format: Texture.SRGB8_Alpha8
generateMipMaps: true
}
//将材料的当前金属度级别保存为 0(纯介电性,默认值)和 1(纯金属性)之间的值。
//这可以是普通的统一值或纹理。 默认情况下,此属性的值为 0。
metalness: TextureLoader { source: "qrc:/assets/textures/aluminium_random_brushed/aluminium_random_brushed_metallic.png"; generateMipMaps: true }
//保持材料的当前粗糙度级别。
//这可以是普通的统一值或纹理。 默认情况下,此属性的值为 0。
roughness: TextureLoader { source: "qrc:/assets/textures/aluminium_random_brushed/aluminium_random_brushed_roughness.png"; generateMipMaps: true}
//保存材质的当前法线贴图纹理。
//这只能是纹理,否则将被忽略。 默认情况下未设置此地图。
normal: TextureLoader { source: "qrc:/assets/textures/aluminium_random_brushed/aluminium_random_brushed_normal.png"; generateMipMaps: true }
//保存材质的当前环境光遮挡贴图纹理。
//这只能是纹理,否则将被忽略。 默认情况下未设置此地图。
ambientOcclusion: TextureLoader { source: "qrc:/assets/textures/no-ao.png" }
}
}
Entity {
id: sphere2
components: [
matSphere2Transform,
matSphere,
matSphere2Material
]
Transform {
id: matSphere2Transform
translation: Qt.vector3d(-1.5, 0, 0)
rotationY: -90
}
MetalRoughMaterial {
id: matSphere2Material
baseColor: TextureLoader {
source: "qrc:/assets/textures/american_walnut_crown_cut/american_walnut_crown_cut_basecolor.png"
format: Texture.SRGB8_Alpha8
generateMipMaps: true
}
metalness: TextureLoader { source: "qrc:/assets/textures/american_walnut_crown_cut/american_walnut_crown_cut_metallic.png"; generateMipMaps: true }
roughness: TextureLoader { source: "qrc:/assets/textures/american_walnut_crown_cut/american_walnut_crown_cut_roughness.png"; generateMipMaps: true }
normal: TextureLoader { source: "qrc:/assets/textures/american_walnut_crown_cut/american_walnut_crown_cut_normal.png"; generateMipMaps: true }
ambientOcclusion: TextureLoader { source: "qrc:/assets/textures/no-ao.png" }
}
}
Entity {
id: sphere3
components: [
matSphere3Transform,
matSphere,
matSphere3Material
]
Transform {
id: matSphere3Transform
translation: Qt.vector3d(0, 0, 0)
rotationY: -90
}
MetalRoughMaterial {
id: matSphere3Material
baseColor: TextureLoader {
source: "qrc:/assets/textures/ceramic_tiles_brown_tomato/ceramic_tiles_brown_tomato_basecolor.png"
format: Texture.SRGB8_Alpha8
generateMipMaps: true
}
metalness: TextureLoader { source: "qrc:/assets/textures/ceramic_tiles_brown_tomato/ceramic_tiles_brown_tomato_metallic.png"; generateMipMaps: true }
roughness: TextureLoader { source: "qrc:/assets/textures/ceramic_tiles_brown_tomato/ceramic_tiles_brown_tomato_roughness.png"; generateMipMaps: true }
normal: TextureLoader { source: "qrc:/assets/textures/ceramic_tiles_brown_tomato/ceramic_tiles_brown_tomato_normal.png"; generateMipMaps: true }
ambientOcclusion: TextureLoader { source: "qrc:/assets/textures/no-ao.png" }
}
}
Entity {
id: sphere4
components: [
matSphere4Transform,
matSphere,
matSphere4Material
]
Transform {
id: matSphere4Transform
translation: Qt.vector3d(1.5, 0, 0)
rotationY: -90
}
MetalRoughMaterial {
id: matSphere4Material
baseColor: TextureLoader {
source: "qrc:/assets/textures/copper_brushed/copper_brushed_basecolor.png"
format: Texture.SRGB8_Alpha8
generateMipMaps: true
}
metalness: TextureLoader { source: "qrc:/assets/textures/copper_brushed/copper_brushed_metallic.png"; generateMipMaps: true }
roughness: TextureLoader { source: "qrc:/assets/textures/copper_brushed/copper_brushed_roughness.png"; generateMipMaps: true }
normal: TextureLoader { source: "qrc:/assets/textures/copper_brushed/copper_brushed_normal.png"; generateMipMaps: true }
ambientOcclusion: TextureLoader { source: "qrc:/assets/textures/no-ao.png" }
}
}
Entity {
id: sphere5
components: [
matSphere5Transform,
matSphere,
matSphere5Material
]
Transform {
id: matSphere5Transform
translation: Qt.vector3d(3, 0, 0)
rotationY: -90
}
MetalRoughMaterial {
id: matSphere5Material
baseColor: TextureLoader {
source: "qrc:/assets/textures/gold_leaf_waste/gold_leaf_waste_basecolor.png"
format: Texture.SRGB8_Alpha8
generateMipMaps: true
}
metalness: TextureLoader { source: "qrc:/assets/textures/gold_leaf_waste/gold_leaf_waste_metallic.png"; generateMipMaps: true }
roughness: TextureLoader { source: "qrc:/assets/textures/gold_leaf_waste/gold_leaf_waste_roughness.png"; generateMipMaps: true }
normal: TextureLoader { source: "qrc:/assets/textures/gold_leaf_waste/gold_leaf_waste_normal.png"; generateMipMaps: true }
ambientOcclusion: TextureLoader { source: "qrc:/assets/textures/no-ao.png" }
}
}
}
Lights.qml
import QtQuick 2.1
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Input 2.0
import Qt3D.Extras 2.0
Entity {
id: lights
// 点光源(脉冲)
Entity {
components: [
//在 Qt 3D 场景中封装点光源对象
PointLight {
color: "red"
intensity: 0.3
//指定点光源的恒定衰减。
//注意:此属性的确切含义和用途取决于材料实现。
constantAttenuation: 1.0
//指定点光源的线性衰减。
//注意:此属性的确切含义和用途取决于材料实现。
linearAttenuation: 0.0
//指定点光源的二次衰减。
quadraticAttenuation: 0.0025
//Animation
//动画类型不能直接在 QML 文件中使用。
//它的存在是为了提供一组通用属性和方法,可用于从它继承的所有其他动画类型。
//尝试直接使用 Animation 类型会导致错误。
//PropertyAnimation
//提供了一种对属性值的更改进行动画处理的方法。
//它可用于以多种方式定义动画:
//例如,在 Transition 中
//要为由于状态更改而更改其 x 或 y 属性的任何对象设置动画,请使用 InOutQuad 缓动曲线:
/*
Rectangle
{
id:rect
width:100;height:100
color:"red"
states:State
{
name:"moved"
PropertyChanges{target:rect;x:50}
}
transitions:Transition
{
PropertyAnimation{properties:"x,y";easing.type:Easing.InOutQuad}
}
}
*/
//In a Behavior
//例如,要对矩形 x 属性的所有更改进行动画处理:
/*
Rectangle
{
width:100;height:100
color:"red"
Behavior on x {PropertyAnimation{}}
MouseArea{anchors.fill:parent;onClicked:parent.x = 50}
}
*/
//作为属性值源
//例如,要重复为矩形的 x 属性设置动画:
/*
Rectangle
{
width:100;height:100
color:"red"
SequentialAnimation on x
{
loops:Animation.Infinite
PropertyAnimation{to:50}
PropertyAnimation{to:0]}
}
}
*/
//在信号处理程序中,例如,在单击时淡出对象:
/*
MouseArea
{
anchors.fill:theObject
onClicked:PropertyAnimation{target:theObject;property:"opacity";to:0}
}
*/
//独立
//例如,要在 500 毫秒内对 rect 的宽度属性进行动画处理,从其当前宽度到 30:
/*
Rectangle
{
id:theRect
width:100;height:100
color:"red"
//这是一个独立的动画,默认情况下不运行
PropertyAnimation
{
id:animation;
target:theRect
property:"width"
to:30;
duration:500
}
MouseArea
{
anchors.fill:parent;
onclicked:animation.running = true
}
}
*/
//根据动画的使用方式,通常使用的属性集会有所不同。
//有关更多信息,请参阅单独的属性文档,以及 Qt 中的动画和转换快速介绍。
NumberAnimation on intensity {
from: 0.3; to: 0.8;
running: true
loops: Animation.Infinite
duration: 1000
easing.type: Easing.CosineCurve
}
},
Transform {
translation: Qt.vector3d(0.0, 5.0, 0.0)
}
]
}
// 定向光(稳定)
Entity {
components: [
DirectionalLight {
worldDirection: Qt.vector3d(0.3, -3.0, 0.0).normalized();
color: "#fbf9ce"
intensity: 0.3
}
]
}
Entity {
components: [
DirectionalLight {
worldDirection: Qt.vector3d(-0.3, -0.3, 0.0).normalized();
color: "#9cdaef"
intensity: 0.15
}
]
}
// 聚光灯
Entity {
components: [
SpotLight {
localDirection: Qt.vector3d(0.0, -1.0, 0.0)
color: "white"
intensity: 5.0
},
Transform {
id: spotLightTransform
translation: Qt.vector3d(0.0, 5.0, 0.0)
rotationZ: -60.0
SequentialAnimation {
loops: Animation.Infinite
running: true
NumberAnimation {
target: spotLightTransform
property: "rotationZ"
from: -60; to: 60
duration: 4000
easing.type: Easing.InOutQuad
}
NumberAnimation {
target: spotLightTransform
property: "rotationZ"
from: 60; to: -60
duration: 4000
easing.type: Easing.InOutQuad
}
}
}
]
}
}
TrefoilKnot.qml
import Qt3D.Core 2.0
import Qt3D.Render 2.0
import Qt3D.Extras 2.9
Entity {
id: root
property real x: 0.0
property real y: 0.0
property real z: 0.0
property real scale: 1.0
property real theta: 0.0
property real phi: 0.0
components: [ transform, mesh, material ]
//此材质使用具有单一渲染通道方法的效果并执行每个片段照明。 为
//OpenGL 3 和 OpenGL ES 3 提供了技术。
MetalRoughMaterial {
id: material
//保持材料的当前基色。
//这可以是纯色值或纹理。
//默认情况下,此属性的值为“灰色”。
baseColor: Qt.rgba( 0.8, 0.0, 0.0, 1.0 )
//将材料的当前金属度级别保存为 0(
//(纯介电性,默认值)和 1(纯金属性)之间的值。
//这可以是普通的统一值或纹理。 默认情况下,此属性的值为 0。
metalness: 0.2
//保持材料的当前粗糙度级别。
//这可以是普通的统一值或纹理。 默认情况下,此属性的值为 0。
roughness: 0.5
}
//用于对网格执行变换。
//Transform 组件不可在多个实体之间共享
//变换被保存为 vector3d scale、四元数旋转和 vector3d 平移组件。
//设置 Transform::matrix 属性后,将其分解为这些变换分量并发出相应的变换信号。
//提供了几个帮助函数来设置转换;
//fromAxisAndAngle 和 fromAxesAndAngles 可用于设置围绕特定轴的旋转,
//fromEulerAngles 可用于设置基于欧拉角的旋转,
//而rotateAround 可用于相对于本地原点围绕特定点旋转对象。
Transform {
id: transform
translation: Qt.vector3d(root.x, root.y, root.z)
rotationX: theta
rotationY: phi
scale: root.scale
}
Mesh {
id: mesh
source: "qrc:/assets/obj/trefoil.obj"
}
}