分块烘焙 + 动态挂载光照贴图

由于小黑还是刚接触渲染和烘焙的小菜鸡,

有大佬看到该文章请给予指点,拜谢。

基于:URP (轻量级渲染管线)

HDRP,我觉得应该是更没有问题的,毕竟专业的

Built-In,经过测试没有问题。

        这两天领导给小黑安排个任务,就是大地图分块烘焙,然后动态挂载光照贴图,我刚接到任务时的内心(什么是光照贴图?怎么动态挂载?大地图分块烘焙要交给我了么?我能弄明白么?),经过开搞,自闭,怀疑自己,小黑成功了!

不过有个前提条件啊,就是需要场景师的配合。

小黑这边出了个Demo,给大家提供参考。

目录

版本:

基于URP项目进行分块烘焙

1:创建项目​

2:创建地图

3:放置物体,体现阴影

4:勾选静态,调整灯光,分块烘焙

5:编写脚本,挂载光照贴图

结束

唠家常

今日无推荐


版本:

Unity  2020.3.13f1c1

基于URP项目进行分块烘焙

1:创建项目

2:创建地图

        小黑的地图是基于插件MeshTerrainEditor弄的,大家如果有别的可以给小黑推荐一下。50*50的两块地形图创建完成,为了快,小黑就直接创建平地了。

3:放置物体,体现阴影

接下来,为了体现我们有光照,我们将加入物体,显示阴影。

能看到我们有三个新GameObject进入场景,并且每个地形图下边都各有一个物体,和一个在地形图之外的Scripts(我自定义的Player)

4:勾选静态,调整灯光,分块烘焙

那地图有了,要被烘焙的物体存在了,我们就要开始干正事了。

①:首先把要烘焙的地形图和他们下边的物体勾选静态

②:更改灯光属性

③:打开灯光设置:Window -> Rendering -> Lighting

④:然后先隐藏其中一块地形图,打开进行烘焙,并且移动地形图上的物体后我们发现确实烘焙完成了。

 ⑤:这时候我们要做一件大事儿!先记录烘焙完成后光照贴图对于物体的偏移量和缩放值等等记录一下然后再把图中粉框标记的内容,连带着他们的.mate文件全部移到Unity外边,后边要用到,所以要保存好!

⑥:接着我们烘焙先Clear清除一波烘焙贴图内容,然后隐藏当前地形图,打开另一块进行烘焙,然后重复第④、⑤步非标红操作,记得把中间的索引改一下。

⑦:接着我们不能进行Clear清除操作了啊。因为我们要用到他们共同的LightingDataReflectionProbe-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,大家一起进步。

今日无推荐

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青衫磊落长歌行

觉得小黑这篇文章不赖,打赏哟~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值