分块烘焙 + 动态挂载光照贴图
由于小黑还是刚接触渲染和烘焙的小菜鸡,
有大佬看到该文章请给予指点,拜谢。
基于:URP (轻量级渲染管线)
HDRP,我觉得应该是更没有问题的,毕竟专业的
Built-In,经过测试没有问题。
这两天领导给小黑安排个任务,就是大地图分块烘焙,然后动态挂载光照贴图,我刚接到任务时的内心(什么是光照贴图?怎么动态挂载?大地图分块烘焙要交给我了么?我能弄明白么?),经过开搞,自闭,怀疑自己,小黑成功了!
不过有个前提条件啊,就是需要场景师的配合。
小黑这边出了个Demo,给大家提供参考。
目录
版本:
Unity 2020.3.13f1c1
基于URP项目进行分块烘焙
1:创建项目
2:创建地图
小黑的地图是基于插件MeshTerrainEditor弄的,大家如果有别的可以给小黑推荐一下。50*50的两块地形图创建完成,为了快,小黑就直接创建平地了。
3:放置物体,体现阴影
接下来,为了体现我们有光照,我们将加入物体,显示阴影。
能看到我们有三个新GameObject进入场景,并且每个地形图下边都各有一个物体,和一个在地形图之外的Scripts(我自定义的Player)。
4:勾选静态,调整灯光,分块烘焙
那地图有了,要被烘焙的物体存在了,我们就要开始干正事了。
①:首先把要烘焙的地形图和他们下边的物体勾选静态
②:更改灯光属性
③:打开灯光设置:Window -> Rendering -> Lighting
④:然后先隐藏其中一块地形图,打开进行烘焙,并且移动地形图上的物体后我们发现确实烘焙完成了。
⑤:这时候我们要做一件大事儿!先记录烘焙完成后光照贴图对于物体的偏移量和缩放值等等记录一下,然后再把图中粉框标记的内容,连带着他们的.mate文件全部移到Unity外边,后边要用到,所以要保存好!
⑥:接着我们烘焙先Clear清除一波烘焙贴图内容,然后隐藏当前地形图,打开另一块进行烘焙,然后重复第④、⑤步非标红操作,记得把中间的索引改一下。
⑦:接着我们不能进行Clear清除操作了啊。因为我们要用到他们共同的LightingData和ReflectionProbe-0。接着我们把两次烘焙出来的内容,全部放入Unity的一个自定义文件夹中,可以从下边看出,小黑是把两次烘焙的结果全部放到了一个叫XHScenessssss文件夹下,并且把第二次烘焙出来的贴图索引改名为1。
至此,我们的分块烘焙,已经完事了,那我们接下来要做的就是把这写贴图挂载到Baked Lightmaps面板下边。
5:编写脚本,挂载光照贴图
小黑的做的不是很好,待优化。分为几个步骤:1清空光照贴图,2增加光照贴图,3给之前烘焙的物体赋值光照贴图。
我们看一下,场景中已经没有任何灯光照射了,被烘焙的两张地形图都有阴影。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ReplaceBakingMap : MonoBehaviour
{
public Texture2D[] MyTexture;
public List<GameObject> MyGameObjects = new List<GameObject>();
public Vector4[] MyVector4;
// Start is called before the first frame update
void Start()
{
}
[ContextMenu("设置LightMap")]
private void SettingLightMap()
{
if (MyTexture.Length == 0)
{
Debug.LogError("MyTextures is null");
return;
}
LightmapData[] __mapData = LightmapSettings.lightmaps;
int __length = __mapData.Length;
LightmapData[] __tempMapData = new LightmapData[__length + MyTexture.Length / 2];
for (int i = 0; i < __length; i++)
{
__tempMapData[i] = __mapData[i];
}
for (int i = 0; i < MyTexture.Length; i+=2)
{
int __indexI = __length + (i / 2);
LightmapData __date = new LightmapData();
__date.lightmapDir = MyTexture[i];
__date.lightmapColor = MyTexture[i + 1];
__tempMapData[__indexI] = __date;
}
LightmapSettings.lightmaps = __tempMapData;
}
[ContextMenu("设置LightMap为空")]
private void SettingLightMapToNull()
{
LightmapSettings.lightmaps = null;
}
[ContextMenu("获取位置")]
private void GetLightmapTexture()
{
int __length = MyGameObjects.Count;
Vector4[] __tempVector = new Vector4[__length];
for (int i = 0; i < __length; i++)
{
__tempVector[i] = MyGameObjects[i].GetComponent<MeshRenderer>().lightmapScaleOffset;
}
MyVector4 = __tempVector;
}
[ContextMenu("设置贴图位置")]
private void SetLightmapTexture()
{
int __length = MyGameObjects.Count;
for (int i = 0; i < __length; i++)
{
MeshRenderer __render = MyGameObjects[i].GetComponent<MeshRenderer>();
__render.lightmapScaleOffset = MyVector4[i];
__render.lightmapIndex = 1;
}
}
}
挂载好脚本之后
有个坑和大家说一声,就是我们的烘焙灯每次烘焙完成后,好像被系统置脏了,即使设置成了实时光也不起反应了。。这个问题出现在我本次使用版本(2020.3.13f1c1)上,不知道别的版本是否也是如此。
对于上边这个问题:已解决,只需要运行一下就好了。。。。。
更新为:2021.08.03
还有一点,如果场景中有N多个同样的物体,再勾选静态后,会静态核批处理,经过静态和批处理的物体可能会发生光照烘焙信息赋值不准确,这时我们就需要把静态合批关掉。然后把需要合批的物体用3D软件做处理就好了。
结束
至此,已经全部完成了,通过本次实践理论,我们可以了解到大地图如何快速加载、快速烘焙了吧。
唠家常
- 小黑的今日分享结束啦,小伙伴们你们get到了么,你们有没有更好的办法呢,可以评论区留言分享,也可以加小黑的QQ:841298494,大家一起进步。
今日无推荐
- 客官,看完get之后记得点赞哟!
- 小伙伴你还想要别的知识?好的呀,分享给你们😄
- 小黑的杂货铺,想要什么都有,客官不进来喝杯茶么?
本文来自博客园,作者:青衫磊落长歌行,转载请注明原文链接:https://www.cnblogs.com/WenhaoWang/p/17073537.html
身负灵石行天下,冲关断喝辨正邪; 仙籍经文誊卷上,日省三身驭鬼神; 奇门遁甲游四方,九星八门断吉凶; 仙宝葫芦聚灵兽,乾坤凝练化神火; 八卦灵镜控震雷,凛然正气荡妖魔; 虚怀若谷尝百草,岐黄妙术展幡旗; 祈符笔走通九幽,素手悬铃摄心魂; 依剑证道心通明,青衫磊落长歌行。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步