第二十二章 光照贴图

news2024/11/23 16:29:34

光照贴图过程将预先计算场景中静态物体表面的亮度,并将结果存储在称为“光照贴图”的纹理中供以后使用。光照贴图可以包含直接光照和间接光照,以及阴影效果。但是,烘焙到光照贴图中的数据无法在运行时更改,这就是为什么移动静态物体后,阴影不会跟随移动。接下来,我们就来演示如何使用光照贴图,我们新创建一个“LightDemo”的工程。在场景中我们创建了几个游戏对象,这些游戏对象的参数详细介绍如下截图所示:

以上是平面Plane的位置参数,它的材质颜色为(96,96,96,255),颜色为灰色系。

这是立方体Cube的位置参数,它的材质颜色为(185,131,13,255),颜色为橙色系。同时,我们调整主光源的位置和旋转方向,让其从Cueb的X轴右侧45度角照射下来,

 

请注意,光源的Z轴方向是照射的方向。

 

以上是两个球体Sphere的位置参数,他们的材质颜色为(135,73,159,255),颜色为紫色系。

当阳光斜射过来的时候,球体Sphere1处于立方体Cube的阴影之中。为了方便观察,我们还是修改一下相机的位置。首先,我们先调整Scene视图的角度,如下

大家可以看到,Scene视图和Game视图的角度是不一样的。我们保持Main Camera选中状态,然后点击菜单栏选择“GameObject”->“Align Width View”。该操作我们之前讲过,就是将Game视图的视角调整到当前Scene视图的视角。如下

两者保持一致了。接下来,我们Play运行一下,

请注意,我们的主光源“方向光”的模式为“混合”,既是实时光照也是烘焙光照。

光源模式设置确定后,我们需要对游戏对象进行一些设置,尤其是外部导入的3D模型。我们知道同一个模型可以使用多张贴图,但是模型的贴图需要UV坐标的支持,因此我们需要让我们的模型支持光照贴图UV。如何让我们的模型支持光照贴图UV呢?操作也非常简单,在“Project”视图中我们选择模型文件,然后在Inspector检视视图中的“Model”选项卡下面找到“Generate Lightmap UVs”,我们点击勾选这个项目即可,从名字上我们就可以得出,这是生成光照贴图UV坐标的意思。对于我们当前场景中的Cube,我们不需要进行此操作。

接下来,我们还需要将所有的游戏物体设置为静态物体(Static),在每个游戏对象的Inspector检视视图中,游戏对象名称右边的Static勾选框,我们点击勾选上,该游戏对象就成为一个静态物体了。在Unity中,物体是可以区分静态和动态的,如果一个物体是静止的,那么该物体在游戏中永远不会移动、旋转和缩放。注意,我们将地面Plane,立方体Cube和球体Sphere1设置为静态物体,而球体Sphere2保持默认的动态物体。

 

 

 

接下来,我们打开Lighting窗口(Window->rendering->lighting setting)。

首先,我们需要点击“New Lighting Settings”创建一个新的光照设置文件,该文件已经在上一章节中创建了,这里我们直接使用即可。在“Lighting Mode”选项一栏,我们选择“Subtractive”模式,也就是将静态物体的直接光照,间接光照和阴影全部烘焙到光照贴图中。在上述窗口的右下角有一个“Generate Lighting”按钮,就是生成光照贴图。点击开始生成光照贴图,等待一段时间后,就制作完毕了。请注意,烘焙的时间根据场景的复杂度不同而不同,我们的场景1-2分钟就结束了,真实地游戏场景可能需要很长很长的时间,几个小时,甚至几十个小时不等。

在上面截图中,Unity为我们生成了一张直接光照的光照贴图,尺寸为512*512像素,大小为2.7M左右。这个文件就位于Project工程面板的“Scenes/SampleScene”目录下

注意,光照贴图是与场景一一绑定的关系。也就是说,场景不一样,光照贴图是不一样的。因为光照贴图被存储到了以场景名称命名的文件夹下。我们在Scene窗口移动静态Cube后发现,它的阴影并没有跟随移动,说明光照贴图起作用了。如下所示

接下来,我们Play运行当前工程

其实没有任何的改变。接下来,我们在运行状态下(Game窗口)调整他们的位置,来查看光照产生的一些效果。静态物体不能在Game窗口下移动,因此我们只给动态物体球体Sphere2添加脚本,代码如下所示:

    void Update()
    {
        if (Input.GetKeyDown(KeyCode.A))
        {
            transform.Translate(Vector3.forward, Space.Self);
        }
    }

我们让Sphere2能够在自身Z轴方向能够移动,运行后效果如下

 

 

 

我们移动动态Sphere2后,发现阴影跟随移动,说明是实时光照其作用。但是,当我们移动Sphere2到Cube的阴影区域的时候,发现明显不对。Sphere2仍然是高亮的效果,它应该与Sphere1一样才对。因为动态物体不会受到光照贴图的影响。

为了让动态物体能够获得光照贴图信息,需要通过在场景中放置采样点将这些信息记录下来,并且在运行时能够让动态物体读取并使用。在Unity中,我们将这些采样点称为“light probe(光照探针)”。Light Probe主要解决了如何在动态物体上使用烘焙的照明信息。光照探针运行时效率非常高并且预计算也很快。接下来,我们就在场景中添加光照探针。

首先,我们菜单栏选择“GameObject”->“Light”->“Light Probe Group”游戏对象。

我们清楚的看到“Light Probe Group”,我们隐藏了其他游戏对象。操作方式就是,选中Light Probe Group”后使用快捷键Shift + H,就会进入Isolation 视图,该视图中只会显示当前选中的游戏对象。退出该视图也非常简单,再次使用快捷键Shift + H或者点击“Exit”退出。默认创建的“Light Probe Group”拥有八个光照探针(小黄球),并且组成一个立方体框架,每一个光照探针位于该立方体的一个顶点上面。我们来查看它的Inspector检视视图,

我们可以点击“Edit Light Probes”按钮来编辑这八个光照探针。你可以选中一个小黄球,移动重新摆放它的位置,也可以Delete键删除它。移动光照探针的操作与我们平时移动游戏对象是一样的。我们还可以选中一个光照探针,按Ctrl + D复制一个新的,然后移动这个新光照探针位置。那么,我们需要将这些光照探针移动到哪里呢?

我们点击“Edit Light Probes”进入编辑状态,然后点击其中一个黄色小球。我们可以选择X/Y/Z三轴来移动黄色小球。那么,我们需要将这些光照探针移动到哪里呢?光照探针是为了采集周围的“光照贴图”里面的光照数据。因此,我们需要将小球放置到Cube的阴影里面,用于获取阴影中的光照信息。这样,当Sphere2移动到阴影中的时候,就会受到阴影中的光照探针的影响。在游戏开发中,我们需要创建大量的光照探针(小黄球),我们该如何摆放他们呢?这里有一个简单的原则,为了提高光照探针的效率,应该在光照变化比较大的地方多放置光照探针,在光照变化不大的地方少放光照探针。比如应该在从明亮到阴影的过渡位置多放光照探针,在反射光较强烈的表面多放置光照探针,在大的平面上少放光照探针。这个道理应该很容易理解,光照探针并不是根据物理区域的大小来放置,而是根据光照信息的复杂程度来放置的。如果在一个很宽阔的区域,只有一个简单的平行光源照射,那么这个区域的光照信息基本是相似的,我们只需要一个或几个光照探针就足够了。总之,尽量让我们的动态物体能够处于我们光照探针的包围之中。一个场景中可以创建多个Light Probe Group游戏对象。目前,我们只需要做一些简单的移动即可,将8个小球放置阴影区域。

最后,我们需要重新烘焙一下。烘焙完成后,我们才能看见光照探头对场景中物体的作用。

烘焙过程中,我们就能看到“Light Probes”的信息了。我们重新Play当前工程,查看效果。

与之前的效果相比,我们的动态Sphere2不再那么明亮了,说明它受到了附近光照探针的影响,这样看起来比较真实一些了。Unity还提供了一个反射探针(Reflection Probe),当场景中不存在反射探针时,场景中带有反射的物体会直接反射天空盒产生的环境信息。当物体处于反射探针范围内时,该物体会反射反射探针范围内的环境信息。它的效果类似于我们日常生活中镜子的效果。这里不介绍了。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python入门教程+项目实战-12.1节: 字典的基础概念

目录 12.1.1 理解字典类型 12.1.2 字典的类型名 12.1.3 字典的定义 12.1.4 在循环中遍历字典 12.1.5 字典的键类型 12.1.6 知识要点 12.1.7 系统学习python 12.1.1 理解字典类型 在日常生活中,我们常常会接触到“字典”这种数据类型,例如一本书籍…

排序篇:直接插入、希尔、直接选择和堆排序(C语言)

目录 前言: 一:插入排序 (1)直接插入排序 基础思路(有个印象就行,主要看单趟): 单趟排序: 完整排序: 时间复杂度分析: (2)希尔排序 基础思路(有个印象就行,主要看单趟)&#…

【2023 年第十三届 MathorCup 高校数学建模挑战赛】D 题 航空安全风险分析和飞行技术评估问题 27页论文及代码

【2023 年第十三届 MathorCup 高校数学建模挑战赛】D 题 航空安全风险分析和飞行技术评估问题 27页论文及代码 1 题目 D 题 航空安全风险分析和飞行技术评估问题 飞行安全是民航运输业赖以生存和发展的基础。随着我国民航业的快速发展,针对飞行安全问题的研究显得…

网络编程 总结一

一、网络基础: 概念:1> 网络编程的本质就是进程间的通信,只不过进程分布在不同的主机上 2>在跨主机传输过程中,需要确定通信协议后,才可以通信 1. OSI体系结构(重点) 定义7层模型&…

针对近日ChatGPT账号大批量封禁的理性分析

文 / 高扬 这两天不太平。 3月31号,不少技术圈的朋友和我闲聊说,ChatGPT账号不能注册了。 我不以为然,自己有一个号足够了,并不关注账号注册的事情。 后面又有不少朋友和我说ChatGPT账号全部不能注册了,因为老美要封锁…

Java笔记_15(不可变集合、Stream流、方法引用)

Java笔记_15 一、创建不可变集合1.1、创建不可变集合的应用场景1.2、创建不可变集合的书写格式 二、Stream流2.1、体验Stream流2.2、Stream流的思想和获取Stream流2.3、Stream流的中间方法2.4、Stream流的终结方法2.5、收集方法collect2.6、练习-数字过滤2.7、练习-字符串过滤并…

Python词云图的制作与案例分享(包含 wordcloud 和 jieba库)

一、基本知识 Python 有很多可用于制作词云图的库,其中比较常用的有 wordcloud 和 jieba。 wordcloud 是一个用于生成词云图的 Python 库,其使用了 Python 的 PIL 库和 numpy 库。您可以使用 pip 命令来安装 wordcloud 库: pip install wo…

第12章 项目沟通管理和干系人管理

文章目录 12.1.2 沟通的方式 404沟通管理计划的编制过程12.2.2 制订沟通管理计划的工具 4114、沟通方法 12.3.2 管理沟通的工具 41312.4.2 控制沟通的技术和方法 4163、会议 12.5.1 项目干系人管理所涉及的过程 420项目干系人管理的具体内容:(1&#xff…

从“青铜”到“王者”,制造企业的数字化闯关记

打过游戏的朋友可能有一个常识,越是精彩纷呈、奖励丰厚的副本,越是需要召集队友一同组团闯关。很多实体企业在数字化转型中,也不会单打独斗,一把手会先找咨询公司对企业内外情况进行调研、梳理、规划,提出一个顶层规划…

科学计算库—numpy随笔【五一创作】

文章目录 8.1、numpy8.1.1、为什么用 numpy?8.1.2、numpy 数据类型推理8.1.3、numpy 指定长度数组快速创建8.1.4、numpy 哪个是行、列?8.1.5、numpy 如何进行数据类型转换?8.1.6、numpy 有几种乘法?8.1.7、numpy 索引和切片操作8.…

2023年前端面试题汇总-代码输出篇

1. 异步 & 事件循环 1. 代码输出结果 const promise new Promise((resolve, reject) > {console.log(1);console.log(2); }); promise.then(() > {console.log(3); }); console.log(4); 输出结果如下: 1 2 4 promise.then 是微任务,它…

【今日重磅—国产大模型首批内测机会来了】什么是讯飞星火,如何获得内测和使用方法

♥️作者:白日参商 🤵‍♂️个人主页:白日参商主页 ♥️坚持分析平时学习到的项目以及学习到的软件开发知识,和大家一起努力呀!!! 🎈🎈加油! 加油&#xff01…

数电实验:Quartus II 软件使用 (八进制计数器和全加器)

一、实验目的: 1.熟悉可编程逻辑器件的设计工具Quartus II 软件的使用。 2.熟悉FPGA开发实验系统的软件环境,掌握各个菜单和图标的作用和功能。 二、实验内容 (1)以74160实现八进制计数器为例,学Quartus II 软件的…

【手撕代码系列】JS手写实现Promise.all

Promise.all() 方法接收一个 Promise 对象数组作为参数,返回一个新的 Promise 对象。该 Promise 对象在所有的 Promise 对象都成功时才会成功,其中一个 Promise 对象失败时,则该 Promise 对象立即失败。 本篇博客将手写实现 Promise.all() 方…

Peforce(Helix) 使用快速介绍

虽然Git应该是当下使用最多的版本控管工具, 但曾经作为版本控管巨头的Perforce还是在持续的发展和更新中, 在某些企业中,还是作为软件的版本控管工具之一。 Helix 截止2023, Perforce 的最新版本的名称是Helix ,这个词翻译的意思是螺旋&…

【手撕代码系列】JS手写实现Promise.race

公众号:Code程序人生,分享前端所见所闻。 Promise.race() 是一个常见的 JavaScript Promise 方法,它接受一个 Promise 数组作为参数,并返回一个新的 Promise 对象。这个新的 Promise 对象在传入的 Promise 数组中,任意…

[架构之路-158]-《软考-系统分析师》-13-系统设计 - 高内聚低耦合详解、图解以及技术手段

目录 第1章 什么是高内聚低耦合 1.1 概念 1.2 目的 1.3 什么时候需要进行高内聚低耦合 1.4 什么系统需要关注高内聚、低耦合 第2章 分类 2.1 内聚的分类 2.2 耦合的分类 第3章 增加高内聚降低耦合度的方法 3.1 增加高内聚 3.2 降低耦合度 第1章 什么是高内聚低耦…

seurat -- 关于DE gene的讨论

实例 # 加载演示数据集 library(Seurat) library(SeuratData) pbmc <- LoadData("pbmc3k", type "pbmc3k.final")# list options for groups to perform differential expression on levels(pbmc)## [1] "Naive CD4 T" "Memory CD4 T…

Orangepi Zero2 全志H616(DHT11温湿度检测)

最近在学习Linux应用和安卓开发过程中&#xff0c;打算把Linux实现的温湿度显示安卓app上&#xff0c;于是在此之前先基于Orangepi Zero2 全志H616下的wiringPi库对DHT11进行开发&#xff0c;本文主要记录开发过程的一些问题和细节&#xff0c;主要简单通过开启线程来接收温湿度…

LeetCode1376. 通知所有员工所需的时间

【LetMeFly】1376.通知所有员工所需的时间 力扣题目链接&#xff1a;https://leetcode.cn/problems/time-needed-to-inform-all-employees/ 公司里有 n 名员工&#xff0c;每个员工的 ID 都是独一无二的&#xff0c;编号从 0 到 n - 1。公司的总负责人通过 headID 进行标识。…