找回密码
 立即注册
查看: 418|回复: 0

[笔记] Unity Lightmap&LightProbe局部动态加载

[复制链接]
发表于 2022-1-2 10:04 | 显示全部楼层 |阅读模式
最終效果




可以实现两套lightmap光照信息和light probe动态切换

背景需求

lightmap部分


  • 通常为了拥有光照效果且平衡性能,项目中常用Lightmap来模拟灯光带来的效果。
  • 但目前有些功能场景仅拥有一个scene,其中的全部资源都是以AssetBundle的形式动态加载。这时,如果需要两套光照效果,就需要开发额外的功能实现lightmap动态加载。
lightprobe部分


  • 动态物体不会受到lightmap的影响,因此当物体在场景中移动时,会因为没受光而显得很突兀。这个问题一般会使用lightprobe来解决。
  • 与lightmap面对的问题一样,当场景中的物体动态加载,且不同物体之间的光照信息并不一致时,就需要动态的替换对应的probe部分。
原理&实现

lightmap部分


  • lightmap会在烘焙后生成一个绑定场景的lightingdata类型的asset文件,该文件和场景一一对应,默认情况下不支持一个场景对应两个data文件的情况。



  • lightingdata文件整体替换的话难度不大,unity已经提供了接口,使用如下接口即可。
LightmapSettings.lightmaps= new LightmapData();

  • 但有时候场景的中的物体加载是独立的,例如场景中有四个房间,这四个房间均有两套独立的光照数据对应,如果继续对它们进行整体替换,则需要保存12套数据,这样实现肯定不行。目前的实现是将prefab对应的光照信息绑定在资源上,在物体被加载进来的时候,动态的修改对应的LightmapIndex和LightmapScaleOffset。
info.renderer.lightmapIndex = lightmapOffsetIndex[info.lightmapIndex];
info.renderer.lightmapScaleOffset = info.lightmapOffsetScale;

  • 这样实现的问题是,一个场景仅能绑定一个lightingdata,该文件的内部数据不能动态的修改,因此需要对场景进行两次烘焙,将第二次烘焙生成的lightingdata数据中需要保留的文件与第一次的数据合并,融合成为一个新的lightingdata文件,并绑定当前场景。这样实现之后,两次烘焙的有效lightmap贴图都被存储在最新的lightingdata文件内。在游戏内,加载资源实例化后,根据存储的信息重新对LightmapIndex和LightmapScaleOffset赋值,即可实现需求。



红光为第一次烘焙数据,黄光为第二次烘焙数据


  • 额外说明,这样实现时,最好让替换的prefab文件不与其他资源的lightmap贴图耦合。尽量做到合并的数据都是有效的。该功能可以通过设置下图的参数实现:


lightprobe部分


  • unity在烘焙完成后,会生成一个存储lightprobe的asset文件,但该文件不是自动生成的,可以使用以下代码手动生成查看一下文件的存储结构。
AssetDatabase.CreateAsset(Instantiate(LightmapSettings.lightProbes), "Assets/lightProbe.asset");

  • 打印出来的文件结构如下图所示。




    • Tetrahedralization里面保存的是LightProbe插值时需要用到的四面体数据,如果物体动态替换时,lightprobe的世界坐标不变的话,这个信息并不需要修改。
    • Probe Sets里面存储的是关于lightprobe group的索引数据。
    • Positions里面的是每个探针的世界坐标。
    • Baked Coefficients里面存储的是烘焙后的球谐函数的系数,unity内部LightProbe使用的是3阶球谐函数(9个参数),因此可以看到一个探针对应"9个参数3个通道",一共27个float数据。LightProbe的原理就是对球面上的亮度信号进行编码和重建,因此该部分为lightprobe的核心数据。我们需要动态替换的就是这里面的数据。





    • 知道原理和存储结构后,我们可以根据probe的世界坐标进行索引,筛选出需要动态替换的probe索引id,并将该部分数据存储在prefab上。由于这部分是在编辑器下进行的,因此一一遍历寻找对性能没有什么影响。
    • 最后,在游戏内加载资源实例化后,根据存储的信息重新对对应的probe进行赋值,即可实现需求。

本帖子中包含更多资源

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

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-24 10:10 , Processed in 0.092302 second(s), 27 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表