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: 640
    height: 480
    visible: true 

    View3D {
        anchors.fill: parent
        environment: SceneEnvironment {
            clearColor: "#333"
            backgroundMode: SceneEnvironment.Color
            antialiasingMode: SceneEnvironment.MSAA
            antialiasingQuality: SceneEnvironment.High
        } 

        camera: camera
        PerspectiveCamera {
            id: camera
            position: Qt.vector3d(0, -500, 500)
            eulerRotation.x: 45
        }

        WasdController {
            id: wasd_control
            controlledObject: camera

         }


        DirectionalLight {
             eulerRotation: Qt.vector3d(0, 0, 0)
             castsShadow: true
             brightness: 3
             shadowFactor: 5
             shadowMapQuality : Light.ShadowMapQualityHigh
        }


        Model {
            source: "#Sphere"
            z: 200
            materials: 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: true

    enableXZGrid : 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: 640
    height: 480
    visible: true

    Column {
        z: 2
           Row {
                Slider {
                    id: slider1
                    from: 0
                    to: 180
                    value: 40
                    focusPolicy: Qt.NoFocus
                    width: 400
                }
                Text {
                    anchors.verticalCenter: slider1.verticalCenter
                    text: "coneAngle:" + slider1.value.toFixed(3)
                    color: "#F00"
                }
           }
           Row {
               Slider {
                   id: slider2
                   from: 0
                   to: 2
                   value: 1
                   focusPolicy: Qt.NoFocus
                    width: 400
               }
               Text {
                   anchors.verticalCenter: slider2.verticalCenter
                   text: "constantFade :" + slider2.value.toFixed(3)
                   color: "#F00"
               }
           }
           Row {
               Slider {
                   id: slider3
                   from: 0
                   to: 180
                   value: 30
                   focusPolicy: Qt.NoFocus
               }
               Text {
                   anchors.verticalCenter: slider3.verticalCenter
                   text: "innerConeAngle :" + slider3.value.toFixed(3)
                   color: "#F00"
               }
           }

           Row {
               Slider {
                   id: slider4
                   from: 0
                   to: 10.0
                   value: 0
                   focusPolicy: Qt.NoFocus
               }
               Text {
                   anchors.verticalCenter: slider4.verticalCenter
                   text: "linearFade :" + slider4.value.toFixed(3)
                   color: "#F00"
               }
           }
           Row {
               Slider {
                   id: slider5
                   from: 0
                   to: 100
                   value: 1
                   focusPolicy: Qt.NoFocus
               }
               Text {
                   anchors.verticalCenter: slider5.verticalCenter
                   text: "quadraticFade :" + slider5.value.toFixed(3)
                   color: "#F00"
               }
           }
    }


    View3D {
        anchors.fill: parent
        environment: SceneEnvironment {
            clearColor: "#333"
            backgroundMode: SceneEnvironment.Color
            antialiasingMode: SceneEnvironment.MSAA
            antialiasingQuality: SceneEnvironment.High
        }

        AxisHelper {
           enableXYGrid: true
           enableXZGrid : false
        }

        camera: camera
        PerspectiveCamera {
            id: camera
            position: Qt.vector3d(0, -300, 300)
            eulerRotation.x: 45
        }

        WasdController {
            id: wasd_control
            controlledObject: camera

         }


        SpotLight {
            z: 300
            brightness: 10
            castsShadow: true
            shadowFactor: 50
            shadowMapQuality : Light.ShadowMapQualityHigh
            bakeMode: Light.BakeModeIndirect

            coneAngle: slider1.value
            constantFade: slider2.value
            innerConeAngle: slider3.value
            linearFade: slider4.value
            quadraticFade: slider5.value

        }


        Model {
            source: "#Sphere"
            z: 100
            materials: 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类

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/248217.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

neo4j如何创建多个数据库

1.在neo4j的压缩包解压位置找到neo4j.conf文件 "D:\neo4j\neo4j-community-3.5.5\conf\neo4j.conf"2.修改文件 新增dbms.activate_database**.db 再重新neo4j打开网页就进入到新建的数据库中 如果要切换,就把原来的注释掉就可以

Python移动未标注的图片数据集

Python移动未标注的图片数据集 前言前提条件相关介绍实验环境Python移动未标注的图片数据集情况一:有图,无标注文件代码实现输出结果 情况二:有图,有标注文件,但标注信息为空代码实现输出结果 情况一与情况二同时都考虑…

Leetcode 455 分发饼干

题意理解: 小孩的饭量: [1,2,7,10] 饼的大小: [1,3,5,7] 当饼的大小>小孩饭量时,小孩就能够吃饱。 求如何分配饼让更多的小孩子能够吃饱。 解题思路: 两种思路: 先把胃口小的孩子用较小的饼来喂饱—…

ida脚本环境开发配置idapythonidacpp三端环境(win,mac,linux)

ida脚本也有一段时间了,一直有个痛点是找不到比较好的方法热重载脚本来实时改动生效,导致开发效率老慢了。固总结下比较友好的环境搭配 使用ida热加载插件让你开发脚本更高效 github地址: GitHub - 0xeb/ida-qscripts: An IDA plugin to increase productivity when developi…

MATLAB 系统辨识 + PID 自动调参

MATLAB 系统辨识 PID 自动调参 Matlab R2021b下载安装详细教程Chapter1 MATLAB 系统辨识 PID 自动调参1. 导入数据2. 系统辨识3. PID 自动调参 Chapter2 MATLAB系统辨识Chapter3 【MATLAB】使用系统辨识工具箱(System Identification)建模Chapter4 matlab系统辨识工具箱及其反…

探索 Coinbase 二层链 Base 的潜力与风险

作者:lesleyfootprint.network 在不断变化的加密货币领域,Coinbase 已经确立了自己领先中心化交易所(CEX)的地位。然而,Coinbase 坚信去中心化是创造一个开放、全球范围内对每个人都可访问的加密经济的关键&#xff0…

Go map转json

今天分享的知识是 Go 接口。如果本文对你有帮助,不妨点个赞,如果你是 Go 语言初学者,不妨点个关注,一起成长一起进步,如果本文有错误的地方,欢迎指出! 但当有的场景,要返回哪些字段…

工作记录-------实现实时排行榜的各种方法---12.14

实时积分排行榜 需求 提供一个用户积分排行榜–为 实时总积分榜, 只取前 10 名 。所有用户都能够查看当前排行榜,以及查看自己的 实时总积分排名 设计实现 先看下数据库的结构,总共有 2 个表:用户表 和 用户积分表。 用户表存储了用户信息,以及用户的总积分(实时更新…

电商控制台前台整合优化

前台逻辑 显示商品菜单输入id,进入某个商品检测登录和注册 根据登录和注册的状态,订单或者是购物车都需要登录。 登录:生成订单(先生成订单表,再生成订单详情表) 开发直接购买,加入购物车, …

计算机毕业设计 基于SpringBoot的日常办公用品直售推荐系统的设计与实现 Java实战项目 附源码+文档+视频讲解

博主介绍:✌从事软件开发10年之余,专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ 🍅文末获取源码联系🍅 👇🏻 精…

做性能测试必须掌握的基本概念和套路

经常听到人说,做个性能优化,吞吐量越高越好;或者做个性能测试,目标TPS是50000。可实际拿到这个信息,能够做性能测试吗?这个目标足够清晰吗?事实上,在我看来,未定义清晰 …

Ubuntu18.04.6下安装opencv库及OpenCV安装libjasper-dev依赖包错误

目录 01 解压安装包 02 安装cmake和依赖库 03 配置编译环境 01 解压安装包 创建一个名为Opencv的文件夹 mkdir opencv 将源码的压缩包复制到opencv目录下 将压缩包解压到opencv文件夹(指定一个文件夹) unzip opencv-3.4.11.zip -d opencv02 安装cm…

Web3.0:抗寻租的互联网平台经济

在数字世界的荒蛮时代,人类的数字大迁徙,纷乱而芜杂,充满着未知与蒙昧。 我们致敬先行者,感恩在黑暗中点亮火把,在泥泞中探索前行的道路。 我们以先行者为师,承续他们的智慧与勇气,在人类数字大…

【强化学习-读书笔记】动态规划(策略评估、价值迭代、策略迭代算法)

参考 Reinforcement Learning, Second Edition An Introduction By Richard S. Sutton and Andrew G. Barto动态规划 (Dynamic Programming, DP) 是一类优化方法,在给定一个用马尔可夫决策过程 (MDP) 描述的完备环境模型的情况下,其可以计算最优的策…

【Jeecg Boot 3 - 保姆级】第1节 docker + redis + nginx + redis一键安装启动

一、前言 ▶ JEECG-BOOT 开源版难以吃透的原因 ▶ 为了针对上面痛点,笔者做了如下安排 ▶ 你能收获什么 二、效果(第一节效果) ▶ 启动后端 > 日志 > 接口文档 ▶ 启动前端 三、准备工作 四、实战 ▶ 1、服务器安装 Stag…

RF模块是如何工作的?

射频(RF)模块使用无线电频率工作,这个频率范围在30kHz到300kHz之间变化。 在这个射频系统中,数字数据被表示为载波波幅度的变化。这种调制类型是振幅移位键。 这个射频模块是射频发射器和接收器的组合,发射器接收器对的…

读书笔记-《数据结构与算法》-摘要6[快速排序]

快速排序 核心:快排是一种采用分治思想的排序算法,大致分为三个步骤。 定基准——首先随机选择一个元素最为基准划分区——所有比基准小的元素置于基准左侧,比基准大的元素置于右侧递归调用——递归地调用此切分过程 快排的实现与『归并排…

伪距单点定位概念与原理、算例分析

目录 一、概念与原理 1.伪距观测值 2.为何被称为"伪距" ? 3.单点定位的概念 4.伪距单点定位的原理 5.伪距单点定位的优缺点 二、伪距观测方程 三、伪距观测方程线性化 1.泰勒级数展开 2.得到线性化后的观测方程 3.在某历元接收机同时观测n颗卫星&#xf…

视频号小店需要缴纳保证金吗?保证金缴纳标准,不懂的快来看!

我是电商珠珠 入驻视频号小店,需要缴纳保证金吗?具体缴纳多少?... 这是想要入驻视频号小店的热门话题,今天我就来给大家一一讲明白。 想要入驻视频号小店,就必须要缴纳保证金。保证金是平台为了约束商家的行为&…

递推与递归练习题

公众号:编程驿站 题目来源于洛谷! 数楼梯 题目描述 楼梯有 N 阶,上楼可以一步上一阶,也可以一步上二阶。 编一个程序,计算共有多少种不同的走法。 输入格式 一个数字,楼梯数。 输出格式 输出走的方…