第二十一章 光源

news/2024/10/30 23:18:20/

光源是每个场景必不可少的部分,光源除了能够照亮场景之外,还可以产生阴影效果。

Unity中分为四种光源类型

1. 方向光:Directional Light 用于模拟太阳光,方向光任何地方都能照射到。

2. 点光源:Point Light 用于模拟电灯泡的照射效果。

3. 聚光灯:Spot Light 用于模拟聚光灯照射效果。

4. 区域光:Area Light 区域光在“实时光照”模式下是无效的,只用于“烘焙光照”模式。

默认场景中会自动给我们添加一个Directional Light方向光,相当于一个太阳。

我们可以选择该光源查看它的Inspector检视视图,光源这个游戏对象,最重要的组件就是Light组件,截图如下所示

接下来,我们稍微解释一下Light组件的一些属性:

Type:当前的光源类型。可选值为 Directional、Point、Spot 和 Area。

Color:使用拾色器来设置发光的颜色。

Mode:指定光源模式。可选模式为 Realtime(实时)、Mixed(混合) 和 Baked(烘焙)。

Intensity:设置光源的亮度。

Indirect Multiplier:使用此值可改变间接光的强度。

如果是Spot聚光灯(Light组件的Type属性为Spot)的话,效果如下:

该类型的光源类似一个圆锥体,它有自己的“Range”和“Spot Angle”两个属性,前者代表光线照射的距离,后者代表圆锥体开合角度,也就是光线照射的范围。如下所示:

如果是Point点光源(Light组件的Type属性为Point)的话,效果如下:

该类型的光源有一个“Range”属性,它表示光线照射的距离,也就是圆球半径值。

最后一个是Area区域光,效果如下:

该类型的光源是通过空间中的矩形来定义的。光线在表面区域上均匀地向所有方向上发射,但仅从矩形的所在的面发射。无法手动控制面光源的范围,但是当远离光源时,强度将按照距离的平方呈反比衰减。由于光照计算对性能消耗较大,因此面光源不可实时处理,只能烘焙到光照贴图中。

光源在 Unity 中非常容易使用,可通过菜单栏 GameObject > Light 将光源添加到场景中。如果启用 Scene 视图光照(工具栏上的“太阳”按钮),则可在移动光源对象并设置其参数时预览光照效果。这里需要注意的是,方向光通常可放置在场景中的任何位置,沿自身Z轴正方向照亮整个场景,没有照射范围的限制,因此方向光跟位置没有关系,跟自身旋转有关系(直接影响物体的阴影位置)。聚光灯有位置,也有方向,但其照射范围是有限。点光源与聚光灯类似,他们都属于局部光源,主要用于场景中一些局部细节的光影效果处理。

光源的使用,有很多技巧。比如,如果游戏场景中必须使用光源,但又不希望一些游戏对象受到该光源的影响。我们可以创建一个图层Layer,并将这些游戏对象添加到该图层Layer中。在光源的检视面板中找到Culling Mask剔除遮罩属性,在下拉列表中选择该图层。那么该图层中所有游戏对象不在受到该光源的影响了。

关于光源这一块内容,大家不要忽略“环境光”,它是一个真真正正的全局光照,能够从四面八方照向游戏物体,也就是说,它不会产生阴影效果。我们可在 Lighting 窗口中找到环境光设置,默认它来自于天空盒材质贴图(光的本质就是颜色)。打开方式为菜单栏 “Window”->“Rendering”->“Lighting”,在弹出的新窗口中点击选中“Environment”。

Environment Lighting 该项为物体提供环境光。颜色来源可以是上面设定的Skybox天空盒材质球,可以使固定的颜色或渐变色。2D游戏中一般不需要任何光源,只需要设置环境光即可。我们顺便说一下下面的Environment Reflections ,该项控制环境光反射设置,同样也来源于Skybox天空盒材质球,它提供的是镜面反射效果,是基于物理的渲染(PBR)中重要的照明效果。也就是说,如果场景中有一个镜子的话,镜子里面呈现的是天空盒的样子。但是,如果这个镜子在一个房间里面的话,镜子里面呈现天空盒的样子,就不太合理了。Unity提供反射探针(Refletion Probe)技术,用于捕捉周围场景的图像,并将其储存为立方体贴图Cubemap。房间里面的镜子就可以通过反射探针(Refletion Probe)来呈现周围的景象。也就是说,当物体处于反射探针范围内时,该物体会反射反射探针范围内的环境信息。当场景中不存在反射探针时,场景中带有反射的物体会直接反射天空盒产生的环境信息。

这里,我就继续介绍一下天空盒。我们在DirectX课程中介绍过,它其实就是模拟现实世界中的天空。最简单的天空盒,就是一个立方体贴图而已。Unity中的天空盒本质是一个材质球。我们可以从Unity Asset Store中下载一些免费的天空盒,例如下面这个。

下载完之后,我们就可以导入当前工程中,如下所示

 

其中“Materials”目录下就是很多的天空盒材质球,而“Scenes”是给我们提供的一个场景。我们可以点进入“Scenes”看一看。

双击“Demo.unity”这个场景文件,如下所示

运行之后的效果如下

接下来,我们回到“Materials”目录下查看

上图中展示了很多的天空盒材质球,他们的本质也就是一张贴图而已。这些天空盒材质球如何使用呢?我们回到之前的默认场景,然后点击菜单栏:Window > Rendering > Lighting,再选择Environment选项面板,如下所示

我们要做的就是,将我们的材质球拖到上面红色标注的框中即可。

我们之前的场景是这样的,也就是默认的天空盒(Default-Skybox)。

改成“FS000_Day_01”之后的样子

接下来,我们介绍一下光照贴图(LightMap。大家需要明白的是,光照效果的计算是非常消耗硬件性能的,如果我们在游戏中每时每刻都要对所有的物体进行光照计算而得出其表现效果,这显然不是一个最好的方式。因此,我们可以将光照信息提前“烘焙”到贴图中,在游戏运行后,不再进行实时光照计算,而是直接从物体的光照贴图中获取信息,达到与之前一样的表现效果。Unity引擎为我们提供了功能强大的光照贴图功能,让美术人员可以在Unity编辑器里方便的烘焙光照贴图。但是,缺点就是这些光照贴图只能应用于静态物体(static,也就是不能移动的物体,并且表现效果是固定不变的,这个大家应该能够很容易理解。在上面介绍光源模式的时候,可选模式为 Realtime、Mixed 和 Baked三种。Realtime是实时光照,Baked是烘焙光照,Mixed是两者兼顾(默认项)。根据名称,我们就能大概理解这三种模式的用途了,烘焙光照的含义是会根据该光源烘焙光照贴图,光照贴图生成完毕后,该烘焙光源就可以不使用了,场景中的静态物体依然是之前的光照效果,但是动态物体就没有光照效果了,而且你如果移动静态物体的话,静态物体的阴影是不跟随移动的。这样看来,烘焙光照固然减少了计算性能,但是它不能满足动态物体的光照效果要求。那么,这个问题如何解决呢?其实就是Mixed模式,既可以保证静态物体的光照贴图效果,也可以额保证动态物体的实时光照效果。

接下来介绍两个概念:直接光照和间接光照

直射光照(Direct Lighting):光源直接照射到物体表面所产生的光照信息。

间接光照(Indirect Lighting):光源照射到物体表面以后再反射到其他物体上所形成的光照信息。间接光照让我们的场景更加逼真,因为这比较符合我们现实世界的真实光照情况。这就好比我们在一个物体旁边放置一面镜子,来自镜子的间接光照肯定会对这个物体产生光照效果的。但是,间接光照的实现需要支持实时光线追踪的硬件才能实现,比如Nvidia的RTX系列显卡。因此,在低端PC以及大部分手机上,我们还得依赖预先计算好的光照贴图来提供这些间接光照信息。没错,光照贴图既可以存储直接光照信息,也可以存储间接光照信息。在Unity中,光源主要控制的是直接光照,Lighting窗口主要控制的是间接光照。

接下来介绍另一个概念:全局光照系统(约等于烘焙)

全局光照系统是对直接光照和间接光照进行建模以提供逼真光照效果的一组技术。Unity 有两个全局光照系统:烘焙全局光照系统(Baked Global Illumination)和实时全局光照系统(Realtime Gloabl lllumination)。烘焙全局光照系统包括光照贴图、光照探针和反射探针。所有渲染管线均支持烘焙全局光照系统。实时全局光照系统包括使用 Enlighten 的实时全局光照,并为光照探针增加了额外功能。请注意,目前已弃用 Enlighten,很快就会从 Unity 中删除实时全局光照系统。这样看来,Unity全局光照主要用于烘焙光照贴图了。那么,我就来介绍一下Unity的烘焙全局光照系统,需要在Lighting窗口中进行设置。我们通过菜单栏Window -> Rendering -> Lighting打开Lighting窗口,然后点击选中“Scene”选项

默认情况下,没有光照配置,我们需要点击“New Lighting Settings”生成一个

同时在Project工程面板中,也会生成同名的光照配置文件,

我们回到“Scene”选项卡中有“Realtime Lighting”和“Mixed Lighting”两个选项。他们分别代表了烘焙全局光照系统(Baked Global Illumination)和实时全局光照系统(Realtime Gloabl lllumination)。从截图中,我们可以看出实时全局光照系统已经被废弃调了,剩下的就是烘焙全局光照系统,也就是在“Mixed Lighting”(混合光源)选项下面。为什么是混合光源?Unity默认的光源模式就是混合光源,也就是既支持实时光照,又支持烘焙,并且在烘焙的时候还支持全局光照技术(直接光照+间接光照的混合)。因为,我们上文中已经提到,烘焙光源虽然减少了性能计算,但是无法解决动态物体的光照需求。所以,动态物体还得需要实时光源才能解决。如果说,场景中既存在烘焙光源,又存在实时光源,那么光照贴图技术还有啥作用呢。当然有了,区别就在于静态物体和动态物体嘛。这道理很简单,烘焙光源用于静态物体,实时光源用于动态物体。所以说,光源推荐使用混合方式,尤其是主光源。

我们看到在“Mixed Lighting”下面有两个子选项,一个是启动烘焙全局光照系统的勾选框,另一个是“Lighting Mode”,默认值为“Shadowmask”。Shadowmask 模式下将烘焙间接光照效果到光照贴图中(也就是说间接光照不进行实时计算),同时直接光照产生的阴影也会被烘培到光照贴图中(也就是说阴影也不进行实时计算了)。也就是说,当运行工程时,改变混合光源不会影响间接光照和静态物体的阴影(固定在光照贴图里面),但其他渲染仍然是按照实时光源进行计算。因此,该模式是实时光照和光照贴图相结合的方式。需要注意的是,通用渲染管线 (URP) 不支持 Shadowmask 光照模式,虽然是默认选项。

另外还有两种模式可以选择:Baked Indirect和Subtractive。

Baked Indirect模式下,只烘培间接光照(也就是说间接光照不进行实时计算),直接光照以及阴影进行实时计算,因此性能的消耗比较大。请注意,该模式在三种渲染管线中都支持。

Subtractive模式下,同时烘焙直接光照和间接光照到光照贴图中,同时也会将静态物体的阴影也烘焙到光照贴图中。请注意,高清渲染管线 (HDRP) 不支持 Subtractive 光照模式。

三种模式对比而言,Subtractive模式性能消耗最低,因为静态物体的直接光照,间接光照和阴影都从光照贴图中获取,不再进行实时计算,当然动态物体肯定还是需要光源的实时计算的。请注意,对性能消耗最低,但是高清渲染管线不支持。其次是Shadowmask模式,该模式只烘焙静态物体的间接光照和阴影,直接光照仍然按照实时光照计算而得,相比较前者模式,性能消耗大一些。虽然性能消耗比较折中,也是Unity默认选项,但是通用渲染关系不支持。最后是Baked Indirect模式,该模式值烘焙间接光照,直接光照和阴影仍然按照实时光照计算而得,显然性能消耗最大。虽然性能消耗最大,但是所有渲染管线都支持。因此, 大家在进行游戏开发之处,就需要将这些内容确定了,选择那种渲染管线和那种模式。

在Lighting窗口中,我们还能看到Lightmapping Settings选项,下面有一些重要参数。

Lightmapper:指定使用哪个内部照明计算软件来计算场景中的光照贴图。Unity 使用一个名为渐进光照贴图 (Progressive Lightmapper) 的计算系统。默认Progressive CPU,表示采用CPU进行计算,还可以选择Progressive GPU进行计算。另外Enlighten已废弃(上面说过)。

Direct Samples:直接光照采样值

Indirect Samples:间接光照采样值

Environment Samples:环境光采样值

最后就是那个Auto Generate勾选项,如果我们勾选此项的话,Unity会自动帮我们生成光照贴图;如果我们不勾选(默认情况),我们需要点击右边的“Generate Lighting”来手动生成光照贴图。如果我们修改了光照或者场景的话,我们就需要重新生成光照贴图了。

最后我们来总结一下:Unity的四种光源类型很容易理解。比较难理解的是Unity的间接光照,它主要目的还是为了让场景更加的逼真,但是很遗憾的是,间接光照仅能用于烘焙,也就是用来生成光照贴图。光照贴图技术在Unity中大量被采用,因此光源模式才有了实时,烘焙和混合三种。默认情况下,我们推荐使用混合模式下的光源,烘焙光照贴图后,场景中的静态物体将从光照贴图中获取光照效果,而动态物体仍然通过实时光源计算获得光照效果。这样,既能保证整体的光照效果,又能减少性能的消耗。关于光照贴图的烘焙设置,需要大家了解Lighting窗口中的“Mixed Lighting”中“Lighting Mode”的三种模式。他们的区别就在于是否将直接光照,间接光照和阴影烘焙到光照贴图中,烘焙的内容越多,实时计算量就越少,这个应该不难理解。


http://www.ppmy.cn/news/58658.html

相关文章

Oracle中按天、周、月、季、年统计数据

简介: oracle实现按照天、周、月、季、年进行数据统计,在实际业务场景中如 "报表之类" 、"财务业务的往来" 等等,业务往往需要我们统计整年 或 整月的数据等,下面我们直入主题。 说明: 原始数据 一、按天查询 1、片段 …

BeautifulSoup4学习笔记

.string–获取文本内容 html <html><head><title>The Dormouses story</title></head><body><p class"title" name"dromouse"><b>The Dormouses story</span></b></p>><p cla…

Java 基础进阶篇(六)—— 接口详解

文章目录 一、接口概述二、接口的基本使用三、接口从 JDK 8 开始新增的方法四、接口的注意事项&#xff08;了解&#xff09;补充&#xff1a;接口与接口的关系 一、接口概述 规范的基本特征是约束和公开。 接口就是一种规范&#xff0c;其约束别人必须干什么事情。 所以&…

自供电-测力刀柄资料整理

自供电-测力刀柄资料整理 2. 相关专利2.1 实时测量铣削过程中床主轴温度装置【1】2.2 一种基于应变片的测力系统【2】 3. 相关商业化产品3.1 spike 测力刀柄【3】3.2 瑞士奇石乐&#xff08;Kistler&#xff09;旋转切削测力仪【4】3.3 kistler的通用型压电式切削力测量系统3.4…

Linux Ansible导入剧本、任务滚动执行、任务并行执行

目录 任务滚动更新 配置并行 包含和导入剧本 任务滚动更新 实现在多台被管理节点执行任务时&#xff0c;第一台的整个playbook执行完成后再在下一台主机执行任务&#xff1b;通过serial元素来实现 serial&#xff1a;1 表示一台一台执行playbook&#xff08;serial也可以指定…

Python基础合集 练习23 (错误与异常语句处理3)

‘’’ raise语句 raise[ExceptionName[(reason)]] 其中ExceptionName[(reason)]是可选参数用来指定抛出异常名称和原因,如果省略该参数,就会原样输出当前的错误 ‘’’ 在下面程序中,使用raise语句抛出ValueError异常 def num_calu(): book int(input(输入图书数量: )) stu…

MySQL知识学习05(InnoDB存储引擎对MVCC的实现)

1、一致性非锁定读和锁定读 一致性非锁定读 对于 一致性非锁定读&#xff08;Consistent Nonlocking Reads&#xff09; &#xff0c;通常做法是加一个版本号或者时间戳字段&#xff0c;在更新数据的同时版本号 1 或者更新时间戳。查询时&#xff0c;将当前可见的版本号与对…

【IDEA Sprintboot】简单入门:整合SpringSecurity依赖、整合Thymeleaf框架

目录&#xff1a; 1、【IDEA】简单入门&#xff1a;请求数据库表数据_水w的博客-CSDN博客 目录 三、 1、整合SpringSecurity依赖 2、整合Thymeleaf框架 解决css样式等静态资源访问不到的问题 三、 1、整合SpringSecurity依赖 Spring Security是一个能够为基于Spring的企业…