无限大地图:lightmap拆分

//创建LightmapParameters资源文件
public static void CreateLightmapParameterFile(string path, int bakeTag)
{
LightmapParameters lp = new LightmapParameters();
lp.bakedLightmapTag = bakeTag;
AssetDatabase.CreateAsset(lp, path);
AssetDatabase.ImportAsset(path);
} public static void SetRenderLightmapParameters(Renderer renderer, string giparamsFile)
{
SerializedObject so = new SerializedObject(renderer);
var sp = so.FindProperty("m_LightmapParameters");
sp.objectReferenceValue = AssetDatabase.LoadAssetAtPath(giparamsFile, typeof(LightmapParameters));
so.ApplyModifiedProperties();
}
重点在so.FindProperty("m_LightmapParameters");这是一个不对外的成员变量,通过反射来获取,然后设置objectReferenceValue ,关联之前创建的LightmapParameters文件。后面就简单了,自己实现吧
//获取uv2
public static Vector2[] GetMeshUV2(Mesh m)
{
//如果不存在uv2,则使用uv代替
var uv2 = m.uv2;
if (uv2 == null || uv2.Length == 0)
uv2 = m.uv; return uv2;
} //计算uv的范围
public static Vector4 GetBounds(Vector2[] uv, Renderer r)
{
if (uv != null)
{
var __uv = new Vector2[uv.Length];
Array.Copy(uv, __uv, uv.Length);
uv = __uv;
var minx = float.MaxValue;
var miny = float.MaxValue;
var maxx = float.MinValue;
var maxy = float.MinValue;
for (var _j = 0; _j < uv.Length; ++_j)
{
var _uv = uv[_j];
if (_uv.x < minx)
{
minx = _uv.x;
}
if (_uv.y < miny)
{
miny = _uv.y;
}
if (_uv.x > maxx)
{
maxx = _uv.x;
}
if (_uv.y > maxy)
{
maxy = _uv.y;
}
}
var bounds = new Vector4(minx, miny, maxx, maxy);
return bounds;
} return Vector4.zero;
} //通过与LightmapScaleOffset计算出原始uv范围对应Lightmap贴图中的范围
public static Vector4 CalcBoundWithLightmapScaleOffset(Vector4 sourceBounds, Vector4 lightmapScaleOffset)
{
var scaleBounds = new Vector4(sourceBounds.x * lightmapScaleOffset.x + lightmapScaleOffset.z,
sourceBounds.y * lightmapScaleOffset.y + lightmapScaleOffset.w,
sourceBounds.z * lightmapScaleOffset.x + lightmapScaleOffset.z,
sourceBounds.w * lightmapScaleOffset.y + lightmapScaleOffset.w); return scaleBounds;
} //这里就是扣图了
public static Texture2D PickTexture(Texture2D sourceTex, Vector4 bounds)
{
var blockW = (int)((bounds.z - bounds.x) * sourceTex.width);
var blockH = (int)((bounds.w - bounds.y) * sourceTex.height);
int startX = (int)(bounds.x * sourceTex.width);
int startY = (int)(bounds.y * sourceTex.height); //startY = (tex.height - startY - blockH);
if (blockH == 0 || blockW == 0)
return null; var colors = sourceTex.GetPixels(startX, startY, blockW, blockH);
Texture2D tex2d = new Texture2D(blockW, blockH);
tex2d.SetPixels(colors);
tex2d.Apply();
return tex2d;
} //从整lightmap贴图中扣指定物件的光照贴图
public static Texture2D PickLightmap(GameObject go, out Vector4 bound)
{
bound = Vector4.zero;
if (go == null)
return null; var meshFilter = go.GetComponent<MeshFilter>();
var renderer = go.GetComponent<Renderer>();
if (meshFilter == null || renderer == null)
return null; var tex = GetFullLightmap(renderer);
var uv2s = GetMeshUV2(meshFilter.sharedMesh);
//var bounds = GetBounds(uv2s, renderer);
var sourceBounds = LightMapUtil.GetBounds(uv2s, renderer);
var scaleBounds = CalcBoundWithLightmapScaleOffset(sourceBounds, renderer.lightmapScaleOffset);
bound = sourceBounds; return PickTexture(tex, scaleBounds);
}
public static void CombineRendererInfos2(List<RendererInfo> rdInfoList, out Rect bound, out Rect[] packedRects)
{
packedRects = new Rect[]; //计算总面积
int areaAll = ;
for(int i = ; i < rdInfoList.Count; ++i)
{
areaAll += (rdInfoList[i].MyLightmap.width * rdInfoList[i].MyLightmap.height);
} //计算最接近这个面积的宽高尺寸
int size = ;
while(true)
{
if (size * size > areaAll)
break;
size *= ;
} bound = new Rect(, , size, size); if (areaAll == )
return; while (true)
{
List<Rect> rectList = new List<Rect>();
List<Texture2D> texList = new List<Texture2D>();
rectList.Add(bound);
for (int i = ; i < rdInfoList.Count; ++i)
{
Texture2D tex = new Texture2D(rdInfoList[i].MyLightmap.width, rdInfoList[i].MyLightmap.height);
texList.Add(tex);
} Texture2D combined = new Texture2D((int)bound.width, (int)bound.height, TextureFormat.ARGB32, false); packedRects = combined.PackTextures(texList.ToArray(), , size); if (packedRects == null || packedRects.Length == || packedRects[].width * bound.width < texList[].width)
{
bound.width *= ;
bound.height *= ;
size *= ;
}
else
{
bound.width = combined.width;
bound.height = combined.height;
for (int i = ; i < rdInfoList.Count; ++i)
{
Vector2 pos = new Vector2(packedRects[i].x, packedRects[i].y);
{
rdInfoList[i].Position = pos;
rdInfoList[i].Position.x *= bound.width;
rdInfoList[i].Position.y *= bound.height; //为了消除接缝黑边
var ignorPixels = /1f;
var blockW = rdInfoList[i].MyLightmap.width;
var blockH = rdInfoList[i].MyLightmap.height;
var texWidth = bound.width;
var texHeight = bound.height;
var sourceBounds = rdInfoList[i].OldBound; var scaleUVX = (blockW - ignorPixels) / (texWidth * (sourceBounds.z - sourceBounds.x));
var offsetUVX = (pos.x) / (float)texWidth - scaleUVX * sourceBounds.x; var scaleUVY = (blockH - ignorPixels) / (texHeight * (sourceBounds.w - sourceBounds.y));
var offsetUVY = (pos.y) / (float)texHeight - scaleUVY * sourceBounds.y; rdInfoList[i].MyLightmapScaleInfo = new Vector4(scaleUVX, scaleUVY, offsetUVX, offsetUVY);
}
}
break;
}
}
}
无限大地图:lightmap拆分的更多相关文章
- Unity 场景分页插件 World Streamer 支持无限大地图的解决方案(二)
Terrain Streaming 可以用WorldCreator创建Tile地形,然后用WorldStreamer实现分块地图.比如10000*10000(16平方公里) 的地形,需要1000*10 ...
- 《MFC游戏开发》笔记七 游戏特效的实现(一):背景滚动
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9344721 作者:七十一雾央 新浪微博:http:// ...
- 百度王一男: DevOps 的前提是拆掉业务-开发-测试-运维中间的三面墙
这是一个创建于 375 天前的主题,其中的信息可能已经有所发展或是发生改变. 由数人云.优维科技.中生代社区联合发起的 系列 Meetup < DevOps&SRE 超越传统运维之道&g ...
- HBase性能优化完全版
近期在处理HBase的业务方面常常遇到各种瓶颈,一天大概一亿条数据,在HBase性能调优方面进行相关配置和调优后取得了一定的成效,于是,特此在这里总结了一下关于HBase全面的配置,主要参考我的另外两 ...
- supermap iobect .net 7.1.2 图例的拆分
LayoutSelection objLytSelect = m_MapLayoutControl.MapLayout.Selection;//.Selection; //LayoutSelectio ...
- 首师大附中互测题:50136142WXY的坑爹百度地图【B006】(可以喝的超大桶水)
[B006]50136142WXY的坑爹百度地图[难度B]——————————————————————————————————————————————————————————————————————— ...
- Android中调用百度地图
一.调用百度地图 --第一种方法 1.下载百度地图SDK SDK可以拆分下载,需要使用那一部分功能就下载相应包含的SDK,如下图 核心的的jar 和so包,放在工程中的libs目录下 2.申请key ...
- 《MFC游戏开发》笔记十 游戏中的碰撞检测进阶:地图类型&障碍物判定
本系列文章由七十一雾央编写,转载请注明出处. http://blog.csdn.net/u011371356/article/details/9394465 作者:七十一雾央 新浪微博:http:// ...
- js调用百度地图接口
原文:js调用百度地图接口 这是前几天公司做的新项目,上面需要用到地图的数据.第一次做这类型的东西没啥思路,咱们经理说,这东西简单,截个图存文件夹里调整好尺寸,数据库里存上图片的地址动态调用就行了.心 ...
随机推荐
- 201521123061 《Java程序设计》第八周学习总结
201521123061 <Java程序设计>第八周学习总结 1. 本周学习总结 2. 书面作业 1.List中指定元素的删除(题目4-1) 1.1 实验总结 主要是应用到了list中的a ...
- 201521123040《Java程序设计》第7周学习总结
1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 参考资料: XMind 2. 书面作业 1.ArrayList代码分析 1.1 解释ArrayList的contains源代 ...
- 201521123032《Java程序设计》第5周学习总结
1. 本周学习总结 1.1 尝试使用思维导图总结有关多态与接口的知识点. 1.2 可选:使用常规方法总结其他上课内容. 参考资料: 百度脑图 XMind 2. 书面作业 作业参考文件下载 1. 代码阅 ...
- 201521123049 《JAVA程序设计》 第10周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图你的提交结果(出 ...
- Markdown 练习
一个例子: 例子开始 1. 本章学习总结 今天主要学习了三个知识点 封装 继承 多态 2. 书面作业 Q1. java HelloWorld命令中,HelloWorld这个参数是什么含义? 今天学了一 ...
- NA笔记
常用配置命令 mstsc 远程桌面控制指令(在运行中输入) cmd 运行 copy running-config start 正在启动文件 copy running-config startup-ci ...
- Java 最常用类(前1000名) 来自GitHub 3000个项目
这篇文章主要介绍了最常用的1000个Java类(附代码示例),需要的朋友可以参考下 分析Github 3000个开源项目,粗略统计如下.括号内的数字是使用频率 0-3000. 下面的列表显示不全,完整 ...
- Python内置函数详解
置顶 内置函数详解 https://docs.python.org/3/library/functions.html?highlight=built#ascii https://docs.pyth ...
- 为bookStore添加权限【动态代理和注解】
前言 目前为止,我们已经学习了动态代理技术和注解技术了.于是我们想要为之前的bookStore项目添加权限控制-.. 只有用户有权限的时候,后台管理才可以进行相对应的操作-.. 实现思路 之前我们做权 ...
- OSGi-入门篇之服务层(03)
前言 作为OSGi框架中最上面的一层,服务层带给了我们更多的动态性,并且使用了大家或多或少都曾了解过的面向服务编程模型,其好处是显而易见的. 1 什么是服务 简单的说,服务就是“为别人所做的工作”,比 ...