人气 319

[烘焙相关] 完全理解Unity中PreCompute Realtime GI及其优化(一) [复制链接]

九艺网 2019-10-31 20:28:01

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?注册

x
   Unity作为目前最流行的游戏开发引擎,在移动端也提供了良好的光照效果,帮我们构建更加真实的游戏场景。我们知道,一个游戏场景的真实与否,效果是否出色,有一部分来自光照。逼真的光照,总能表现出令人赞叹的效果。但要完全模拟现实中的光照,对CPU来说却是一件不可能完成的任务。通常,我们会使用一些方法来近似模拟这些效果。比如烘焙光,光照贴图,阴影贴图等。
   在Unity中的预计算全局光照有两种,烘培光和预计算全局光。后者在Unity中被称作Precompute Realtime GI,准确的说应该称为预计算实时全局光。那么问题来了,既然是实时,又怎么是预计算的呢?

一.什么是预计算实时全局光
我们知道,无论是烘焙全局光照,还是预计算实时全局光照,都是Unity为了提供更复杂的光照效果,同时避免实时光照计算在运行时带来的大量的性能消耗而产生的解决方案。Unity中的预计算实时全局光,和烘焙全局光类似。不同的是,它不但预计算了我们在构建场景时,已经设定好的光在该表面中的反射,同时它还计算了任意可能的光,在该表面会造成的反射效果,这就是它和烘焙全局光不同的地方。

烘焙全局光只能处理静态的物体,并且其光源在运行时和烘焙时需要保持一致,可以认为是一个完全静态的场景。预计算全局光将各种可能的光照的反射信息预计算后,编码保存起来,供运行时使用。因为,虽然也要求针对静态的物体,但却可以处理在运行时,有一定改变的光源。它的适应性比烘焙全局光更好。所以我们可以通过它获得更好的光照效果,和比较好的运行时性能表现。当然,在预计算阶段,它要做的工作就相对要多一点,这也是我们要针对它进行优化的原因。

二.概念
现在我们已经理解了什么是预计算实时全局光,在进一步介绍如何使用和优化预计算全局光之前,我觉得有必要先给大家介绍下其中要涉及到的几个概念。

(1)texel纹素
所谓的纹素,就是根据一个uv坐标,在贴图上采样出的那一个像素,被称为纹素。纹素拥有了在指定uv坐标下的贴图信息。如果是材质贴图,就包含了色彩信息。对于本篇所讨论的光照贴图而言,就是相应的光照信息。

(2)Realtime Resolution 实时光照分辨率
决定了在世界空间下,1单位能拥有多少纹素。

比如当该值为1时,就代表了Unity中的1单位拥有一个纹素。当其大于1是,就代表1单位拥有更多的纹素,其小于1时,代表需要多个单位来使用1个纹素。因为一个单元需要的纹素越多,那么相应的light map的分辨率就越大。分辨率的上升,会带来细节的提升,但是也会对内存,性能造成影响。这在后面我们会进一步解释。

值得注意的时,unity对于这个概念的说明其实很容易造成理解上的误区,使我们认为,这个值其实就是直接决定了最终生成的light map的分辨率。实际上,这个值仍只是一个系数,它间接影响light map的分辨率。它将和后面提到的lightmap parameter参数中的Resolution相乘来得到最终的分辨率大小。最终的分辨率大小是基于每个物体的,并不是说我们设置了Realtime Resolution后,整个场景的光照贴图就是统一按这个分辨率生成了。

Q:那么Realtime Resolution有什么用呢,为什么不直接使用lightmap parameter参数中的Resolution呢?
A:这是因为,如果没有这样一个参数的化,就需要手动的为每一个需要烘焙进light map的物体设置lightmap Parameter,通过其中的lightmap Resolution来指定分辨率。当场景中我们有大量的物体时,这个工作就变的不是很有效率了。所以通过Realtime Resolution可以对场景的大部分物体指定一个默认的分辨率,来简化这一过程。

其实,在lightmap的Setting窗口中,也是可以指定一个lightmap Parameter的。Unity可以使用这个lightmap parameter数据来指定场景默认的lightmap的分辨率,这样就不需要增加一个Realtime Resolution的概念。但可能是考虑到如果这样的话,对分辨率的调整就需要修改项目中所有的lightmap parameter,而不能简单的通过调整一个Realtime Resolution来进行缩放吧。这个属于我的分析,所以也不要太在意,重要的是理解Realtime Resolution的作用和使用方法。

(3)Vexel 体素
体素也不是Unity所独创的一个概念,百度的话,可以得到如下的解释:

一如其名,是数字数据于三维空间分割上的最小单位,体素用于三维成像、科学数据与医学影像等领域。

其实简单的理解,我们可以认为是3D空间的像素。我们知道像素在2D中是正方形的,那么相应的体素就是正方体了。那么一个3D空间的模型体素话后,就是有许多的正方体构成的(想象一下MineCraft)

(4)Cluster 簇
如果使用Google翻译,那翻译成的是集群,但是我认为从其概念上代表的更像是一个单位,所以我用簇来代替,因为在磁盘系统中有簇这个概念,而我觉得在这里,unity想表示的更接近这个概念,所以我就用簇来翻译cluster,如果有更恰当的翻译,也欢迎告知。

好,言归正传。簇简单的理解就是场景的体素化代理。在这里,我想解释的是代理(proxy)这个过程,理解了它,也就能很好的理解簇了。代理,在这里是我们使用体素来表示静态场景几何模型的表面,并将这些体素用于光照计算的这样一个过程。我们将复杂的几何表面,通过体素化,简化为一个个由立方体所代表的表面。然后由这些立方体的某一个表面组成我们要进行光照计算的几何表面。这时,这些体素就被称为簇(cluster)

(5)UV Shell
UV Shell是一个美术更能理解的概念。因为这在拓展UV上会经常接触到。我并不是专业的美术,只是学过一点皮毛,所以这里就勉为其难的从开发的角度说一些我对这个概念的认知。
UV Shell是拓展模型UV时,一块模型拓展后的区域就是shell,一个模型可能会被拓展成一个shell,或是多个,这取决于拓展的方式方法和技术。

我们知道一个模型可能有很多的面(这里不是值顶点构成的三角形面,而是从更直观的认知上看到的面)。比如一个正方体,就有六个面。展uv时,我们可以将这6个面展成一个(cubemap)区域,也可以展成6个区域。那么这个区域就是shell。如果对于更复杂的模型,同样的,也许我们有办法将整个模型的面展成一个区域,也可能因为面的复杂度,我们要展成多个区域。无论如何,知道区域就是shell就可以了

(6)UV Chart
和UV Shell相关的概念,就是uv chart。这个概念应该是unity中提出的。首先我们需要记住,chart是一个正方体的小块。我们展好的shell,它的轮廓则是任意的,我们用N个chart来覆盖这个轮廓的区域,那么最终形成的一块边全是由正方形组成的区块,就是uv chart

总结:

     以上就先把相关涉及到的概念和知识点做一个简单的说明,接下来就会来介绍预计算全局光照中具体的概念的作用和相关的优化方法。
————————————————

原文链接:https://blog.csdn.net/duotemplar/article/details/80554342
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

QQ|手机版|小黑屋|九艺游戏动画论坛 ( 津ICP备2022000452号-1 )

GMT+8, 2024-5-1 22:59 , Processed in 0.068865 second(s), 23 queries .

Powered by Discuz! X3.4  © 2001-2017 Discuz Team.