4.qml 3D-Light、DirectionalLight、PointLight、SpotLight、AxisHelper类深入学习

本文主要是介绍4.qml 3D-Light、DirectionalLight、PointLight、SpotLight、AxisHelper类深入学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天我们学习灯光类

首先来学习Light类,它是所有灯光的虚基类,该类是无法创建的,主要是为子类提供很多公共属性。

常用属性如下所示:

  • ambientColor : color,该属性定义在被该光照亮之前应用于材质的环境颜色。默认值为黑色 rgb(0,0,0)。
  • bakeMode : enumeration, 该属性控制灯光在烘焙光照中是否处于活动状态,例如在生成光照贴图时,取值如下所示:
    • Light.BakeModeDisabled 默认值,该灯不用于烘焙照明
    • Light.BakeModeIndirect 间接照明烘焙。直接照明(漫反射、镜面反射、实时阴影贴图)通常在运行时计算。在运行时,当不处于烘焙模式时,渲染器将尝试对光照贴图进行采样以获取间接光照数据,并将其与实时计算的结果相结合。
    • Light.BakeModeAll 直接照明烘焙,(漫射、阴影)和间接照明均针对此光线进行烘焙, 从 Qt 6.4 开始,不支持镜面反射照明,因此此类灯光不会有镜面反射,也不会生成实时阴影贴图,但它始终会产生烘焙阴影。在运行时,当不处于烘焙模式时,渲染器将尝试对光照贴图进行采样,以代替漫反射光照和阴影贴图的标准实时计算。
  • brightness : real, 灯光亮度,默认为1.0
  • castsShadow : bool, 投射阴影开关。默认值为false,如果bakeMode设置为Light.BakeModeAll,该属性没有任何作用。直接照明烘焙会始终有阴影
  • color : color,此属性用于此灯光照明模型的颜色。默认值为白色,rgb(255, 255, 255)。
  • scope : Node,作用域属性,该属性用于选择场景中的节点。只有该节点及其子节点才会受到此光的影响。默认情况下该值为 null,表示未选择范围。
  • 需要注意的是,使用scope后,那么castsShadow属性将会不起作用,如果必须要阴影,可以将bakeMode设置为Light.BakeModeAll
  • shadowBias : real,阴影偏移, 当对象在自身上投射阴影时,此属性用于调整阴影效果。取值范围为[-1.0,1.0]。一般来说,[-0.1,0.1]内的值就足够了。默认值为 0。
  • shadowFactor : real, 阴影系数, 取值范围为[0,100],其中0表示没有阴影,100表示光线完全阴影。默认值为5。
  • shadowFilter : real,此属性设置阴影的模糊程度。默认值为5,为0表示不模糊
  • shadowMapFar : real, 该属性确定阴影映射的最大距离。较小的值可以提高地图的精度和效果。缺省值为5000。
  • shadowMapQuality : enumeration,该属性设置为阴影渲染创建的阴影映射的质量。低质量使用较少的资源,但产生较低质量的阴影,而高质量使用更多的资源,但产生更好质量的阴影。默认值Light.ShadowMapQualityLow。

1.DirectionalLight平行光

平行光可以理解为遥远的太阳,发出的光线都是平行的,并且被方向光照射的整个区域收到的光照强度都一样。

方向光发出的所有光线都是平行的,可以认为是距离很远的光源,例如遥远的太阳光就是方向光,方向光不像聚焦光那样距离目标越远越暗淡,被方向光照射的整个区域收到的光照强度都一样。

光的默认方向是从Z正方向照射到XY平面。

示例代码如下所示:

import QtQuick
import QtQuick.Window
import QtQuick3D
import QtQuick3D.Helpers
Window {width: 640height: 480visible: true View3D {anchors.fill: parentenvironment: SceneEnvironment {clearColor: "#333"backgroundMode: SceneEnvironment.ColorantialiasingMode: SceneEnvironment.MSAAantialiasingQuality: SceneEnvironment.High} camera: cameraPerspectiveCamera {id: cameraposition: Qt.vector3d(0, -500, 500)eulerRotation.x: 45}WasdController {id: wasd_controlcontrolledObject: camera}DirectionalLight {eulerRotation: Qt.vector3d(0, 0, 0)castsShadow: truebrightness: 3shadowFactor: 5shadowMapQuality : Light.ShadowMapQualityHigh}Model {source: "#Sphere"z: 200materials: DefaultMaterial {diffuseColor: Qt.rgba(0.6, 0.5, 0.2, 1.0)}}Model {source: "#Rectangle"scale: Qt.vector3d(10, 10, 1)materials: DefaultMaterial {diffuseColor: Qt.rgba(0.7, 0.2, 0.2, 1.0)}}}
}

效果如下所示:

PS: WasdController类是用来wasd按键控制辅助类,Model类是模型类,后面会学习,这里用的是一个自带的球体模型

如上图可以看到光照是从球体上方照射而下的。刚好从Z正方向照射到XY平面。

如果我们对xyz分布有时候分不清的话,可以使用AxisHelper网格类.

AxisHelper网格类

AxisHelper类是一个网格助手类,需要import QtQuick3D.Helpers,它用来区分3D中xyz方向, 默认X 轴为红色,Y 轴为绿色,Z 轴为蓝色。

我们在上个示例代码中添加AxisHelper:

运行后效果如下所示:

可以看到很奇怪,默认XZ平面为网络格,也就是底面的意思。3DMax导入的模型一般都是xz为底面,y为高度,所以我们导入模型的时候,一般通常它是以XZ为水平面。

如下图所示,通常只有y或者z为高度,很显然AxisHelper类默认是z-up类型:

如果我们要设置AxisHelper类为y-up,改为如下所示:

AxisHelper {enableXYGrid: trueenableXZGrid : false}

效果如下所示:

PointLight点光源

和现实中的灯泡类似,,从光的中心向各个方向发射强度相同的光。 所以我们移动一个点光源将改变光源发出的位置。如下图所示:

它的光照亮度是通过constantFade、linearFade和SquadicFace属性的值向黑暗方向下降,其中灯光计算为constantFade+distance *(linearFade*0.01)+distance ^2 *(SquadicFade*0.0001)

其中distance 就是每个被照射的位置的距离。

提供的属性介绍如下所示:

  • constantFade:光衰减项的常数因素。默认值是1.0,(值越大,灯光越暗,与距离无关)
  • linearFade: 这个属性增加了灯光效果与光线的距离成比例地变暗的速度。默认值是0.0,这意味着光线没有线性渐变,值越大时,距离越远越暗, 在计算光衰减之前,这里使用的值要乘以0.01。
  • quadraticFade: 这个特性增加了照明效果使光线变暗的比率,与平方反比定律成比例。默认值是1.0,值越大时,距离越远成平方比例变暗,,即当与物体的距离增加一倍时,光强度减少到1/4。在计算光衰减之前,这里使用的值乘以0.0001

SpotLight聚光灯

和现实中手电筒类似,聚光灯的行为类似于PointLight, 但是只会向一个方向发射光, 照亮空间内的一个锥形区域,如下图:

提供的光衰减公式:constantFade + distance * (linearFade * 0.01) + distance * (quadraticFade* 0.0001)^2

PS:该公式计算出来的值越大,则表示光线强度越暗,

提供的属性如下所示:

  • coneAngle : real,此属性定义边缘衰减截止角度,超过该角度后光线就会被截止掉。以 0 到 180 之间的度数定义。默认值为 40。
  • constantFade : real,该特性是光衰减项的常数因子。默认值为 1.0,值越大越暗(设置可见光的整体暗度)
  • innerConeAngle : real,内部的边缘衰减截止角度,默认值为30,超过该角度后就会出现光线衰减,如果值大于等于coneAngle后,那么内部边缘则没有光线衰减
  • linearFade : real,线性渐变比例,默认值为0,则表示照亮后的位置没有线性渐变,值越大渐变效果越暗
  • quadraticFade : real,二次方线性渐变比例,默认值为 1.0,当物体距离加倍后,光强度将会降至1/4,值越大渐变效果越暗

SpotLight使用示例

接下来我们便来写一个示例,来看看属性作用,效果图如下所示:


 

coneAngle 和innerConeAngle 区别

如下图所示,coneAngle 为50.668, innerConeAngle 为64时,由于innerConeAngle >=coneAngle ,所以内部边缘则没有渐变阴影

当我们设置innerConeAngle 为20度左右时,如下图所示,可以看到超过20度的范围有了光线衰减:

完整代码如下所示:

import QtQuick
import QtQuick.Window
import QtQuick3D
import QtQuick3D.Helpers
import QtQuick.Controls
Window {width: 640height: 480visible: trueColumn {z: 2Row {Slider {id: slider1from: 0to: 180value: 40focusPolicy: Qt.NoFocuswidth: 400}Text {anchors.verticalCenter: slider1.verticalCentertext: "coneAngle:" + slider1.value.toFixed(3)color: "#F00"}}Row {Slider {id: slider2from: 0to: 2value: 1focusPolicy: Qt.NoFocuswidth: 400}Text {anchors.verticalCenter: slider2.verticalCentertext: "constantFade :" + slider2.value.toFixed(3)color: "#F00"}}Row {Slider {id: slider3from: 0to: 180value: 30focusPolicy: Qt.NoFocus}Text {anchors.verticalCenter: slider3.verticalCentertext: "innerConeAngle :" + slider3.value.toFixed(3)color: "#F00"}}Row {Slider {id: slider4from: 0to: 10.0value: 0focusPolicy: Qt.NoFocus}Text {anchors.verticalCenter: slider4.verticalCentertext: "linearFade :" + slider4.value.toFixed(3)color: "#F00"}}Row {Slider {id: slider5from: 0to: 100value: 1focusPolicy: Qt.NoFocus}Text {anchors.verticalCenter: slider5.verticalCentertext: "quadraticFade :" + slider5.value.toFixed(3)color: "#F00"}}}View3D {anchors.fill: parentenvironment: SceneEnvironment {clearColor: "#333"backgroundMode: SceneEnvironment.ColorantialiasingMode: SceneEnvironment.MSAAantialiasingQuality: SceneEnvironment.High}AxisHelper {enableXYGrid: trueenableXZGrid : false}camera: cameraPerspectiveCamera {id: cameraposition: Qt.vector3d(0, -300, 300)eulerRotation.x: 45}WasdController {id: wasd_controlcontrolledObject: camera}SpotLight {z: 300brightness: 10castsShadow: trueshadowFactor: 50shadowMapQuality : Light.ShadowMapQualityHighbakeMode: Light.BakeModeIndirectconeAngle: slider1.valueconstantFade: slider2.valueinnerConeAngle: slider3.valuelinearFade: slider4.valuequadraticFade: slider5.value}Model {source: "#Sphere"z: 100materials: DefaultMaterial {diffuseColor: Qt.rgba(0.6, 0.5, 0.2, 1.0)}}Model {source: "#Rectangle"scale: Qt.vector3d(10, 10, 1)materials: DefaultMaterial {diffuseColor: Qt.rgba(0.7, 0.2, 0.2, 1.0)}}}
}

未完待续,下章学习Model类

这篇关于4.qml 3D-Light、DirectionalLight、PointLight、SpotLight、AxisHelper类深入学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/499632

相关文章

Java并发编程必备之Synchronized关键字深入解析

《Java并发编程必备之Synchronized关键字深入解析》本文我们深入探索了Java中的Synchronized关键字,包括其互斥性和可重入性的特性,文章详细介绍了Synchronized的三种... 目录一、前言二、Synchronized关键字2.1 Synchronized的特性1. 互斥2.

一文带你深入了解Python中的GeneratorExit异常处理

《一文带你深入了解Python中的GeneratorExit异常处理》GeneratorExit是Python内置的异常,当生成器或协程被强制关闭时,Python解释器会向其发送这个异常,下面我们来看... 目录GeneratorExit:协程世界的死亡通知书什么是GeneratorExit实际中的问题案例

Java进阶学习之如何开启远程调式

《Java进阶学习之如何开启远程调式》Java开发中的远程调试是一项至关重要的技能,特别是在处理生产环境的问题或者协作开发时,:本文主要介绍Java进阶学习之如何开启远程调式的相关资料,需要的朋友... 目录概述Java远程调试的开启与底层原理开启Java远程调试底层原理JVM参数总结&nbsMbKKXJx

Java深度学习库DJL实现Python的NumPy方式

《Java深度学习库DJL实现Python的NumPy方式》本文介绍了DJL库的背景和基本功能,包括NDArray的创建、数学运算、数据获取和设置等,同时,还展示了如何使用NDArray进行数据预处理... 目录1 NDArray 的背景介绍1.1 架构2 JavaDJL使用2.1 安装DJL2.2 基本操

深入解析Spring TransactionTemplate 高级用法(示例代码)

《深入解析SpringTransactionTemplate高级用法(示例代码)》TransactionTemplate是Spring框架中一个强大的工具,它允许开发者以编程方式控制事务,通过... 目录1. TransactionTemplate 的核心概念2. 核心接口和类3. TransactionT

深入理解Apache Airflow 调度器(最新推荐)

《深入理解ApacheAirflow调度器(最新推荐)》ApacheAirflow调度器是数据管道管理系统的关键组件,负责编排dag中任务的执行,通过理解调度器的角色和工作方式,正确配置调度器,并... 目录什么是Airflow 调度器?Airflow 调度器工作机制配置Airflow调度器调优及优化建议最

深入理解C语言的void*

《深入理解C语言的void*》本文主要介绍了C语言的void*,包括它的任意性、编译器对void*的类型检查以及需要显式类型转换的规则,具有一定的参考价值,感兴趣的可以了解一下... 目录一、void* 的类型任意性二、编译器对 void* 的类型检查三、需要显式类型转换占用的字节四、总结一、void* 的

深入理解Redis大key的危害及解决方案

《深入理解Redis大key的危害及解决方案》本文主要介绍了深入理解Redis大key的危害及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着... 目录一、背景二、什么是大key三、大key评价标准四、大key 产生的原因与场景五、大key影响与危

基于Qt Qml实现时间轴组件

《基于QtQml实现时间轴组件》时间轴组件是现代用户界面中常见的元素,用于按时间顺序展示事件,本文主要为大家详细介绍了如何使用Qml实现一个简单的时间轴组件,需要的可以参考下... 目录写在前面效果图组件概述实现细节1. 组件结构2. 属性定义3. 数据模型4. 事件项的添加和排序5. 事件项的渲染如何使用

深入理解C++ 空类大小

《深入理解C++空类大小》本文主要介绍了C++空类大小,规定空类大小为1字节,主要是为了保证对象的唯一性和可区分性,满足数组元素地址连续的要求,下面就来了解一下... 目录1. 保证对象的唯一性和可区分性2. 满足数组元素地址连续的要求3. 与C++的对象模型和内存管理机制相适配查看类对象内存在C++中,规