untiy 为预制体动态加载光照贴图

unity版本为2021.8
预制体不能携带光照贴图信息,只能我们自己准备了
多方查找加自己摸索终于找到了适合新版本的解决方案,直接贴代码

将这个脚本挂到预制体的最上级

using System.Collections;
using System.Collections.Generic;
using UnityEditor;
using UnityEngine;[System.Serializable]
public struct RendererInfo
{public Renderer renderer;//网格物体  网格和地形的光照信息是分开的public Terrain terrain;//地形public int lightmapIndex;public Vector4 lightmapScaleScaleOffset;
}
//记录光照贴图的信息
public class PrefabLightmapData : MonoBehaviour
{public RendererInfo[] m_RendererInfo;public Texture2D[] m_Lightmaps_light;//颜色贴图public Texture2D[] m_Lightmaps_dir;//方向贴图public Texture2D[] m_Lightmaps_shadowmask;//阴影贴图private void Awake() {RebuildLight();}public void RebuildLight(){if (m_RendererInfo == null || m_RendererInfo.Length == 0) return;LightmapData[] lightmapDataArray = new LightmapData[m_Lightmaps_light.Length];for (int i = 0; i < m_Lightmaps_light.Length; i++){LightmapData lightmapData = new LightmapData();if (i < m_Lightmaps_light.Length) lightmapData.lightmapColor = m_Lightmaps_light[i];if (i < m_Lightmaps_dir.Length) lightmapData.lightmapDir = m_Lightmaps_dir[i];if (i < m_Lightmaps_shadowmask.Length) lightmapData.shadowMask = m_Lightmaps_shadowmask[i];lightmapDataArray[i] = lightmapData;}//为预制体的物体应用光照贴图ApplyRendererInfo(m_RendererInfo);LightmapSettings.lightmaps = lightmapDataArray;//将光照贴图应用到Untiy}//应用光照贴图信息到重建的预制体private void ApplyRendererInfo(RendererInfo[] rendererInfoArray){for (int i = 0; i < rendererInfoArray.Length; i++){RendererInfo rendererInfo = rendererInfoArray[i];if (rendererInfo.renderer != null){rendererInfo.renderer.lightmapIndex = rendererInfo.lightmapIndex;rendererInfo.renderer.lightmapScaleOffset = rendererInfo.lightmapScaleScaleOffset;}else if (rendererInfo.terrain != null){rendererInfo.terrain.lightmapIndex = rendererInfo.lightmapIndex;rendererInfo.terrain.lightmapScaleOffset = rendererInfo.lightmapScaleScaleOffset;}}}
}
//自定义inspector面板
[CustomEditor(typeof(PrefabLightmapData))]
public class PrefabLightmapData_Inspector : Editor
{//重写OnInspectorGUI类(刷新Inspector面板)public override void OnInspectorGUI(){//继承基类方法base.OnInspectorGUI();PrefabLightmapData myScript = (PrefabLightmapData)target;//绘制ButtonRect rect = new Rect(0, 0,100,50);if (GUILayout.Button("重新构建烘焙光照")){myScript.RebuildLight();}}
}

在使用下方的脚本完成烘焙后,脚本将自动记录所有模型和地形的烘焙信息,并在运行后自动重建光照贴图,如果我们需要在不运行时查看光照贴图效果,可以手动点击“重新构建烘焙光照”的按钮
在这里插入图片描述

重写烘焙,烘焙完成后自动准备重建光照贴图所需要的信息

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public static class BackeLightMap
{[UnityEditor.MenuItem("Tools/光照/烘焙光照贴图")]private static void GenerateLightmapInfo(){//必须不能是自动烘焙if (UnityEditor.Lightmapping.giWorkflowMode != UnityEditor.Lightmapping.GIWorkflowMode.OnDemand){Debug.LogError("ExtractLightmapData requires that you have baked you lightmaps and Auto mode is disabled.");return;}//烘焙贴图UnityEditor.Lightmapping.Bake();//找到有这个脚本的物体PrefabLightmapData[] prefabs = Object.FindObjectsOfType<PrefabLightmapData>();foreach (var prefabInScene in prefabs){GameObject scenePrefab = prefabInScene.gameObject;List<RendererInfo> rendererInfos = new List<RendererInfo>();//重建光照贴图时需要的信息List<Texture2D> lightmaps_light = new List<Texture2D>();//所有的光照贴图List<Texture2D> lightmaps_dir = new List<Texture2D>();//所有的光照贴图List<Texture2D> lightmaps_shadowmask = new List<Texture2D>();//所有的光照贴图GenerateLightmapInfo(scenePrefab, rendererInfos, lightmaps_light, lightmaps_dir, lightmaps_shadowmask);//获取当前物体的光照贴图信息和光照贴图//为光照贴图信息和光照贴图赋值prefabInScene.m_RendererInfo = rendererInfos.ToArray();prefabInScene.m_Lightmaps_light = lightmaps_light.ToArray();prefabInScene.m_Lightmaps_dir = lightmaps_dir.ToArray();prefabInScene.m_Lightmaps_shadowmask = lightmaps_shadowmask.ToArray();//替换掉已经保存的预制体GameObject sourcePrefab = UnityEditor.PrefabUtility.GetPrefabParent(prefabInScene) as GameObject;//GameObject sourcePrefab = UnityEditor.PrefabUtility.GetCorrespondingObjectFromSource(scenePrefab);if (sourcePrefab != null){UnityEditor.PrefabUtility.ReplacePrefab(scenePrefab, sourcePrefab);}}}//点击按钮生成光照贴图信息private static void GenerateLightmapInfo(GameObject root, List<RendererInfo> rendererInfoList, List<Texture2D> lightmaps_light, List<Texture2D> lightmaps_dir, List<Texture2D> lightmaps_shadowmask){//找到这个物体的所有网格MeshRenderer[] renderers = root.GetComponentsInChildren<MeshRenderer>();//遍历网格foreach (MeshRenderer meshRenderer in renderers){if (meshRenderer.lightmapIndex != -1){//收集光照贴图信息RendererInfo rendererInfo = new RendererInfo();rendererInfo.renderer = meshRenderer;rendererInfo.lightmapIndex = meshRenderer.lightmapIndex;rendererInfo.lightmapScaleScaleOffset = meshRenderer.lightmapScaleOffset;//收集光照贴图//颜色贴图Texture2D lightmap_light = LightmapSettings.lightmaps[meshRenderer.lightmapIndex].lightmapColor;AddLightMapToCheach(lightmaps_light, lightmap_light);//方向贴图Texture2D lightmap_dir = LightmapSettings.lightmaps[meshRenderer.lightmapIndex].lightmapDir;AddLightMapToCheach(lightmaps_dir, lightmap_dir);//shadowmaskTexture2D lightmap_shadowmask = LightmapSettings.lightmaps[meshRenderer.lightmapIndex].shadowMask;AddLightMapToCheach(lightmaps_shadowmask,lightmap_shadowmask);//光照信息rendererInfoList.Add(rendererInfo);}}//找到这个物体的所有网格Terrain[] terrains = root.GetComponentsInChildren<Terrain>();//遍历网格foreach (Terrain terrain in terrains){if (terrain.lightmapIndex != -1){//收集光照贴图信息RendererInfo rendererInfo = new RendererInfo();rendererInfo.terrain = terrain;rendererInfo.lightmapIndex = terrain.lightmapIndex;rendererInfo.lightmapScaleScaleOffset = terrain.lightmapScaleOffset;//收集光照贴图//颜色贴图Texture2D lightmap_light = LightmapSettings.lightmaps[terrain.lightmapIndex].lightmapColor;AddLightMapToCheach(lightmaps_light, lightmap_light);//方向贴图Texture2D lightmap_dir = LightmapSettings.lightmaps[terrain.lightmapIndex].lightmapDir;AddLightMapToCheach(lightmaps_dir, lightmap_dir);//shadowmaskTexture2D lightmap_shadowmask = LightmapSettings.lightmaps[terrain.lightmapIndex].shadowMask;AddLightMapToCheach(lightmaps_shadowmask, lightmap_shadowmask);//光照信息rendererInfoList.Add(rendererInfo);}}}//将一个光照贴图添加进缓存private static void AddLightMapToCheach(List<Texture2D> list,Texture2D texture){if (texture == null) return;int index = list.IndexOf(texture);//查找已有的集合里有没有这个元素,如果没有,返回-1if (index == -1){list.Add(texture);}}
}

工具栏里会出现烘焙按钮,点击烘焙光照贴图,不要再用Unity自己的烘焙了,为场景中所有挂载了PrefabLightmapData 的预制体烘焙光照
在这里插入图片描述

使用方法,先给预制体挂脚本,然后点Tools里的烘焙光照,然后删掉场景的预制体,然后拖一个新的预制体出来,然后运行场景即可

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/700106.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

强化训练:day8(求最小公倍数、数组中的最⻓连续⼦序列、字⺟收集)

文章目录 前言1. 最小公倍数1.1 题目描述1.2 解题思路1.3 代码实现 2. 数组中的最⻓连续⼦序列2.1 题目描述2.2 解题思路2.3 代码实现 3. 字母收集3.1 题目描述3.2 解题思路3.3 代码实现 总结 前言 1. 最小公倍数   2. 数组中的最⻓连续⼦序列   3. 字⺟收集 1. 最小公倍数…

【数据可视化01】matplotlib实例介绍2

目录 一、引言二、实例介绍1.箱线图2.热力图3.3D图 一、引言 接着上一文章【数据可视化01】matplotlib实例介绍1继续介绍matplotlib的实例。 二、实例介绍 在matplotlib中&#xff0c;常用的图形类型包括&#xff1a; 箱线图&#xff08;Box plot&#xff09;&#xff1a;用…

[Java EE] 文件IO (二):文件内容读写-----数据流

&#x1f338;个人主页:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;️热门专栏:&#x1f355; Collection与数据结构 (91平均质量分)https://blog.csdn.net/2301_80050796/category_12621348.html?spm1001.2014.3001.5482 &#x1f9c0;Java …

Seal^_^【送书活动第4期】——《Web渗透测试技术》

Seal^_^【送书活动第4期】——《Web渗透测试技术》 一、参与方式二、本期推荐图书2.1 前 言2.2 关于本书2.3 本书读者2.4 图书简介2.5 作者荐语2.6 编辑推荐2.7 目 录 三、正版购买 掌握Web渗透测试技术&#xff0c;提高Web应用安全性。 一、参与方式 1、关注博主的账号。 2、点…

Qt---项目的创建及运行

一、创建第一个Qt程序 1. 点击创建项目后&#xff0c;选择项目路径以及给项目起名称 名称&#xff1a;不能有中文、不能有空格 路径&#xff1a;不能有中文路径 2. 默认创建有窗口类myWidget&#xff0c;基类有三种选择&#xff1a;QWidget、QMainWindow、QDialog 3. m…

ssl证书免费申请指南

同学们可以私信我加入学习群&#xff01; 正文开始 前言一、购买证书二、创建证书三、 验证证书等待出现如下页面&#xff0c;说明申请成功&#xff1a; ![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/6b6c1dd11d4c467687318552da7cdbb2.png) 总结 前言 今天为大…

企业必看:镭速教你如何测试内网文件传输效率和稳定问题

在现代商业运作中&#xff0c;企业内部文件传输的效率和稳定性对于数据管理和业务流程极为重要。无论是远程工作还是团队协作&#xff0c;高效的文件传输都能显著提升工作效率。今天镭速小编就教你如何测试内网文件传输效率和稳定问题。 1、磁盘性能&#xff0c;即硬盘的读取和…

类图及类的关系

类图&#xff08;Class Diagram&#xff09;是UML&#xff08;Unified Modeling Language&#xff0c;统一建模语言&#xff09;中的一种图&#xff0c;用于描述系统中类的静态结构&#xff0c;包括类的属性、方法以及类之间的关系。 一、类 类&#xff08;Class&#xff09;…

高级查询(一)

解决需求&#xff1a;Excel都可以轻松搞定 分组查询原理&#xff1a; 语法&#xff1a; SELECT …<列名> FROM <表名> [WHERE<条件表达式> ] GROUP BY 参与分组的列 可以与 聚合函数作用的列 一块显示 注意 SELECT列表中只能包含&#xff1a; 1、被分…

勒索软件漏洞?在不支付赎金的情况下解密文件

概述 在上一篇文章中&#xff0c;笔者对BianLian勒索软件进行了研究剖析&#xff0c;并且尝试模拟构建了一款针对BianLian勒索软件的解密工具&#xff0c;研究分析过程中&#xff0c;笔者感觉构建勒索软件的解密工具还挺有成就感&#xff0c;因此&#xff0c;笔者准备再找一款…

gin框架学习笔记(三) ——路由请求与相关参数

参数种类与参数处理 查询参数 在讲解查询参数的定义之前&#xff0c;我们先来看一个例子&#xff0c;当我打开了CSDN&#xff0c;我现在想查看我的博客浏览量&#xff0c;那么我就需要点击我的头像来打开我的个人主页,像下面这样: 我们现在把浏览器的网址取下来&#xff0c;…

uniapp编译H5解决ios的border-radius失效问题,以及ios满屏显示不全的问题

1.解决方案 .card-itemA {width: 650rpx;height: 326rpx;box-shadow: 0rpx 0rpx 30rpx 14rpx rgba(236, 235, 236, 0.25);background: linear-gradient(180deg, #FFFFFF 0%, rgba(255, 255, 255, 0) 100%);border-radius: 60rpx;overflow: hidden;// 兼容ios的圆角问题transfor…