无限大地图: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调用百度地图接口 这是前几天公司做的新项目,上面需要用到地图的数据.第一次做这类型的东西没啥思路,咱们经理说,这东西简单,截个图存文件夹里调整好尺寸,数据库里存上图片的地址动态调用就行了.心 ...
随机推荐
- 201521123005 《Java程序设计》第1周学习总结
1. 本章学习总结 了解JDK/JRE/JVM,学会了如何安装JDK 学会使用控制台和eclipse上运行java代码 了解PTA提交的常见套路 http://www.cnblogs.com/zhrb ...
- Sublime Text 2 -Sidebar 背景色调整为黑色
Sublime Text 2 编辑器: Ctrl+` 输入安装代码,安装package control 插件 ctrl+shift+P : Package install 为什么装不上了呢?出现了什么 ...
- Java课程设计—学生成绩管理系统(54号童欢)
1. 团队课程设计博客链接 http://www.cnblogs.com/wufuckshuo/p/7063183.html 2.个人责模块或任务说明 负责模块/任务:主函数(调用其他的功能函数),添 ...
- 201521123057 《Java程序设计》第10周学习总结
1. 本周学习总结 1.1 以你喜欢的方式(思维导图或其他)归纳总结异常与多线程相关内容. 2. 书面作业 本次PTA作业题集异常.多线程 1.finally 题目4-2 1.1 截图你的提交结果(出 ...
- 201521123018 《Java程序设计》第11周学习总结
1. 本章学习总结 你对于本章知识的学习总结 2. 书面作业 一.互斥访问与同步访问 完成题集4-4(互斥访问)与4-5(同步访问) 1.1 除了使用synchronized修饰方法实现互斥同步访问, ...
- Java:java中BufferedReader的read()及readLine()方法的使用心得
BufferedReader的readLine()方法是阻塞式的, 如果到达流末尾, 就返回null, 但如果client的socket末经关闭就销毁, 则会产生IO异常. 正常的方法就是使用sock ...
- Linux 安装 mysql 并配置
1.下载 下载地址:http://dev.mysql.com/downloads/mysql/5.6.html#downloads 下载版本:我这里选择的5.6.33,通用版,linux下64位 也可 ...
- 【轉】使用jQuery播放/暂停 HTML5视频
jQuery不可以使用play()方法,但js是可以的: document.getElementById('movie1').play(); 解决方法:play并不是jQuery的函数,而是DOM ...
- this的四种绑定形式
一 , this的默认绑定 当一个函数没有明确的调用对象的时候,也就是单纯作为独立函数调用的时候,将对函数的this使用默认绑定:绑定到全局的window对象. 一个例子 function fire ...
- 【JVM命令系列】jmap
命令基本概述 Jmap是一个可以输出所有内存中对象的工具,甚至可以将VM 中的heap,以二进制输出成文本.打印出某个java进程(使用pid)内存内的,所有'对象'的情况(如:产生那些对象,及其数量 ...