Unity 5正式版面世已经一段时间,许多开发者都已经在使用Unity 5进行开发。大家在使用Unity 5时或多或少都会碰到一些问题,今天我们Unity的官方技术工程师,柳振东将在本文中针对Unity 5中全新的Enlighten全局光照系统的一些问题,以及相应的解答与大家进行分享。
        为什么Unity 5的全局光照系统会让大家踩坑呢? 因为Unity 5取缔了Unity 4中使用的Beast全局光照系统,采用了全新的Enlighten全局光照系统。而这两套全局光照系统的算法并不一样,反映到使用上就是各种参数与操作细节的变化。
        对于没有系统学习过计算机图形学的开发者,还是非常建议大家去了解一下全局光照明模型的,因为大家可能对局部光照明模型(就是我们平常所说的实时光照)比较熟悉,有时可能会把局部光照明模型的一些知识用在全局光照明系统上,白白花费时间做了一些无用功。
        下面挑选一些常见问题与大家分享。
        
        为什么场景烘焙出来的lightmap上有Realitime灯光的颜色?

相信不少开发者都为这样的问题头疼过,因为灯光明明是Realtime的,怎么可能会被烘焙到lightmap里面去呢?但是这在Unity 5里并不是一个bug。
        首先我们要知道Unity 5中新增一种全局光照明的使用方式:Precomputed Realtime GI(预计算实时全局光照明),简称:实时GI。而另一种Bake GI就是大家在Unity 4中一直用过来的ligtmap烘焙方式。
        实时GI与Bake GI一样,也需要预先的Bake过程,但是与Bake GI不同,实时GI并不预计算场景中光线的反射信息,而是预计算场景中静态物体表面所有可能的反射光路,然后在游戏运行时结合灯光的位置、方向等信息实时计算出全局光照的结果。
        这个计算机制使得预计算GI具备非常大的优势,在使用预计算GI的灯光,其位置、方向、强度、颜色等各种信息都可以在运行时实时变化。
        举例:使用预计算GI我们就可以在场景中实现非常真实的日光变化效果(别忘了我们其实是在使用全局光照明模型啊,比实时光照效果强多了)。
        但是,问题来了,预计算GI有一点非常容易让人混淆,那就是预计算GI需要灯光类型是Realtime。WTF?Realtime难道不是实时灯光吗?怎么变成全局光照明模型的灯光了?
        Unity 5的灯光属性中增加了一项,叫做Bounce Intensity,如下图所示:

Bounce Intensity是指全局光照中的间接光强度,要理解这点可以简单地把全局光照理解为直接光照与间接光照两部分。直接光照指直接从光源射到物体上的光,而间接光照指从其他物体表面反射而来的光。那么显而易见,直接光照的部分其实就是局部光照模型,也就是实时光照计算出来的结果。
        回到正题,Bounce Intensity在Unity 5 中默认值是1,意思就是说一盏Realtime灯光默认是使用预计算GI的,并且间接光照的强度不做改变(大于1是强制增大间接光照,这在一些由室外光照射入洞穴这类的场合中可能会用到)。而lighting窗口中的预计算GI选项也是默认开启的,如下图所示:

所以如果你并不更改这些设置,即使看起来你好像只使用了Realtime的灯光,但是真正运行的时候却其实是在使用全局光照系统!
        接下来要说明的一点是,只要一盏灯的Bounce Intensity大于0,Unity就会认为你需要使用全局光照系统。那么即使你在lighting窗口中取消勾选Precomputed Realtime GI,Unity依然会尝试使用全局光照。
        既然已经取消了预计算GI的选项,Unity会去使用另外一种全局光照的方式,Bake GI(只要你还勾选着Bake GI)。而结果就是,烘焙出来的lightmap里也有那盏Bounce Intensity大于0的Realtime灯光的信息。
        总结:Unity 5中灯光有个新属性Bounce Intensity,这个值只要大于0系统就会认为你需要使用预计算GI计算这个灯光,而如果此时Precomputed Realtime GI没有被勾选,而Bake GI勾选了那么Unity会把这个灯光也烘焙到lightmap中去。

为什么在Unity 5中动态更换lightmap没有作用?

在场景中动态更换lightmap是挺常用的需求。例如:同一个场景需要白天与黑夜两个时间的效果,那么我们就会烘焙两张不同的lightmap,然后用脚本在运行时切换。在Unity 4中可以通过把lightmap资源load到Texture2D中,然后赋值给一个LightmapData结构,最后赋给LightmapSettings.lightmaps来达到更换当前使用lightmap的目的。
        但是在Unity 5中会发现使用这个方法并不凑效。是因为lightmap没有正确更换吗?不是的,其实lightmap已经更换了,问题是在于此时使用lightmap的物体并不知道自己应该使用哪张lightmap,也不知道要从lightmap的哪个地方开始采样,而这其实就是每个Renderer上的两个参数,lightmapIndex与lightmapScaleOffset。
        现在大家肯定会问为什么在Unity 4中没有问题呢?那是因为这些信息在Unity 4中已经被序列化进场景文件中,当场景加载进来的时候这两个值就被赋回到每个Renderer中。而在Unity 5中,lightmapIndex与lightmapScaleOffset因为多场景编辑的逻辑需要,不再被序列化到场景文件中去了,而是存在于一个伴随lightmap烘焙产生的一个新文件,Lighting Data Asset中去了(这个文件在初期的5.x中叫做lightmapSnapShot)。这个文件与lightmap在同层目录中,并且可以在Editor中随时更换当前使用的LightingData文件,如下图所示:

那么回归正题,既然LightingData文件存储着lightmapIndex与lightmapScaleOffset,那么只要保证LightingData文件能被最终的可执行文件使用不就没有问题了吗?其实这样是没有问题的,如果我们只需要更换灯光条件不同情况下的lightmap,而场景本身并没有更改的话,那么多套lightmap对于场景中的静态物体Renderer而言也只需要同一套lightmapIndex与lightmapScaleOffset信息而已。所以在这种情况下要达到运行时更换lightmap的效果,只要保证lighting窗口的Ligtmaps页面中Light Data Asset里选中了正确的LightingData文件即可(因为很多开发者习惯性删除掉这个文件,因此也就丢失了lightmapIndex与lightmapScaleOffset信息)。
        简单的情况我们简单地使用LightingData文件即可。但是还有一种情况,如果我们需要场景本身也有所改变要怎么办呢?
        举例:我可能需要原始的场景lightmap与一个被炸弹破坏过后的场景lightmap,由于场景中的静态物体有所改变,这个时候两次烘焙会产生两个数据不同LightingData文件,无法简单使用其中一个。然而比较可惜的是现在Unity并不能在运行时切换LightingData文件,其设计之初就仅仅作为Editor使用的资源。
        那么对于这种情况,我们需要自己记录下每个Renderer上的lightmapIndex与lightmapScaleOffset信息,然后在更换lightmap的时候把这个信息还原回去。
        具体做法有很多种,基本原理都是把lightmapIndex与lightmapScaleOffset序列化起来。比如说我们可以给每个静态物体挂一个脚本,在里面定义一个包含Render,lightmapIndex与lightmapScaleOffset的结构,然后一个Save函数用来在每次烘焙lightmap之后把lightmapIndex与lightmapScaleOffset序列化进结构中,一个Load函数用来在切换lightmap时还原每个Renderer的lightmapIndex与lightmapScaleOffset信息。现在这个问题就解决了。

详解Unity 5 全局光照系统Enlighten问题(上)相关推荐

  1. 详解Unity 5 全局光照系统Enlighten问题(下)

    昨天在 Unity 5 全局光照系统Enlighten问题的文章中,我们为大家解答了:"为什么场景烘焙出来的lightmap上有Realitime灯光的颜色?"和"为什么 ...

  2. 详解Unity中的Nav Mesh新特性|导航寻路系统 (二)

    前言 第一篇我们简要概述了新版NavMesh的一些新增功能,以及旧版的对比.本篇我们来讲一讲NavMeshSurface.NavMeshLink这两个组件的参数以及如何应用,接下来就进入正题吧. 本系 ...

  3. 详解Unity中的粒子系统Particle System (六)

    前言 今天写粒子系统的第六篇文章,讲到这,一些主要模块其实已经讲完了,剩下的就是一些无关紧要或者更加高级的模块了,比如涉及到物理碰撞模块的,涉及到光照系统模块的等等.今天先把剩余无关紧要的模块给讲了, ...

  4. 详解Unity中的粒子系统Particle System (二)

    前言 上一篇我们简要讲述了粒子系统是什么,如何添加,以及基本模块的介绍,以及对于曲线和颜色编辑器的讲解.从本篇开始,我们将按照模块结构讲解下去,本篇主要讲粒子系统的主模块,该模块主要是控制粒子的初始状 ...

  5. 详解Unity中的粒子系统Particle System (四)

    前言 上一篇我们主要讲解了Shape形状模块,以及Emission发射模块,这是粒子系统中最为重要的两个模块,学会了它们我们足以做出惊艳的效果,比如霰弹枪的发射,蘑菇蛋的冲击波等等.本篇讲的内容依旧重 ...

  6. 详解Unity中的粒子系统Particle System (七)

    前言 本篇来讲一讲Collision和Triggers模块,这两个模块主要用于粒子系统与物理世界的交互,一个是碰撞器,另一个是触发器.有了这两个模块我们又可以做出更炫酷的粒子效果啦! 目录 前言 本系 ...

  7. 详解Unity中的粒子系统Particle System (十)

    前言 第十篇,我们讲Light模块和Trails模块,这两个模块不像前几篇所讲的模块一样基本都是对粒子的运行逻辑变化产生影响的,而是对粒子的呈现效果产生影响.比如爆炸粒子不能只有爆炸,还要有光亮,被炸 ...

  8. 详解Unity中的粒子系统Particle System (九)

    前言 今天讲Texture Sheet Animation模块,先前我们已经讲了很多很多模块,通过上述模块可以实现很酷的效果,但是缺了一点真实感.比如说爆炸特效,仅指望单独的粒子来模拟真实的爆炸效果是 ...

  9. 详解Unity中的角色控制器

    前言 如何让玩家所操纵的角色动起来,这在Unity中很容易实现,但是如何确保玩家所操作的角色不会产生一些非常违反物理常识的情况?而这就需要进行大量的检测,已确保玩家所操纵的角色正常.所幸Unity为我 ...

最新文章

  1. 【原创】MyEclipse反编译添加jadclipse_3.3.0 曲折的完美解决
  2. Flutter:Stream.periodic 示例
  3. 2019年工程造价表_住建部发布2019年工程造价咨询企业数据统计公报!
  4. java 持久_Java持久锁总结 -解道Jdon
  5. 33款你可能不知道的开源爬虫软件工具
  6. C++——析构函数为什么要为虚函数
  7. python爬取知乎live_Python爬虫从入门到放弃(十九)之 Scrapy爬取所有知乎用户信息(下)...
  8. mybatis源码分析执行流程
  9. 【Noip模拟 20161005】公约数
  10. (三)进程各种id:pid、pgid、sid、全局pid、局部pid
  11. 360奇舞团钟恒:选用Vue.js进行组件化开发,我们遇到了哪些坑?
  12. Docker 生产环境之安全性 - 适用于 Docker 的 AppArmor 安全配置文件
  13. 关于 continue 用法
  14. python turtle画中国象棋_python使用turtle绘制国际象棋棋盘
  15. matlab如何弄上标,[转载]在Matlab中怎样输入特殊符号或者上标、下标
  16. 深刻理解空间(线性空间,度量空间,赋范空间,线性赋范空间,内积空间,巴拿赫空间以及希尔伯特空间)
  17. 数据分析师要求mysql的_做数据分析师sql需要掌握到什么程度
  18. 人工智能算力网络:独属中国的AI产业发展杀手锏
  19. 计算几何:正多边形的滚动与旋轮线…
  20. IEC 61131标准系列

热门文章

  1. 营收结构多元化,美图的新故事能否如愿?
  2. oracle 分区表空间压缩,Oracle 压缩表/表空间
  3. 奥巴马2008年父亲节的演讲
  4. ES6 Promise对象和then()的用法
  5. 谈女人的风度和气质(ZT)
  6. Flink SQL 自定义 Sink
  7. DJ音乐软件苹果版-Native Instruments Traktor Pro v3.4.0.237 macOS
  8. 灵性图书馆:好书推荐-《巴夏:来自未来的生命讯息》
  9. server精简版代理意外终止 sql_MSSQLSERVER 服务意外终止 ,新安装的操作系统和数据库,怎么解决?...
  10. html页面加载触发的事件,jquery页面加载触发onchange事件