Unity大密度建筑场景加载解决方案

现在虚拟城市仿真,以及军事仿真项目越来越多,开发此类项目,首先面对的一个比较棘手的问题是内存管理,城市中的建筑物特别多,这些建筑物的面数和贴图都要被加到内存中的,内存有自己的峰值,超过了就要崩掉,所以内存的优化是必须要面对以及解决的问题。 
Unity官方提供了Occlusion Culling的裁剪操作,网上有很多文章对它做了相关介绍,因为它是Unity自身提供的,对于我们程序员来说就是一个黑盒子,并不利于我们自己去进一步的优化,最好的方式就是自己通过代码重新实现一个Occlusion Culling算法,当然对于城市仿真只做Occlusion Culling是不能完全解决问题的,我们需要从几个方面入手搞定它,本篇博文就给读者介绍这些针对密集建筑物的优化。下面先看看虚拟仿真的场景: 

面对这么复杂的场景,我们该如何去解决呢?本篇博客教给开发者解决问题的方法,我们会从五个方面来实现我们的密集建筑物解决方案。

AutoLOD

摄像机是用来裁剪的,我们可以设置摄像机的远裁剪面距离做一些优化操作,当然如果是在飞行模拟,这种方法是不可取的,因为我们要求视野是足够大的,这样摄像机视锥体内的物体肯定会很多的,效率就会下降,解决这个问题很自然的想到LOD算法,虚拟场景中的建筑是非常多的,我们不可能让美术帮我们把每个建筑都进行减面处理,工作量是相当大的,LOD是根据摄像机的距离远近相应的显示不同面数的建筑物,我们需要想一种能够自动帮我做LOD处理的算法,AutoLOD就是为解决这个问题而生的。LOD模型显示如下所示: 


AutoLOD是Unity官方为我们提供了一个比较好的插件,可以帮我们自动实现LOD算法,进而对场景中的建筑物进行优化,代码下载地址: 
https://github.com/Unity-Technologies/AutoLOD 
将其代码导入到项目工程中后,然后需要我们做一些设置操作: 


AutoLOD实现的效率比较高,占的显存少,测试的结果如下所示:

其实我们还可以找到一种更好的算法,结合AutoLOD算法一起优化建筑物的面数以及材质,也是第二个步骤要讲解的内容——Amplify Impostors插件,下面介绍Amplify Impostors插件。

Amplify Impostors

这个是Asset store提供的解决方案,它的基本原理是根据摄像机的距离,将原物体生成一个仿真物体,仿真物体面数非常少的,外形跟原物体几乎是一样的,而且还可以旋转,缩放,位移,并且可以投影,效果如下所示: 


仿真对象的生成,我们可以使用GPU实例化,该技术非常适合用于移动端,它对于面数的优化非常好,运行效率测试如下所示: 
 
在实际项目运行中,看一下树木模型实现的效果图如下所示: 

除了对模型的优化,我们还可以对纹理图片进行优化,对应的是Amplify Texture。 
代码下载地址: 
链接:https://pan.baidu.com/s/1VKRwmn7QCzjIM0mqnq0RCA 密码:yrko

Amplify Texture

Amplify Texture是一种纹理虚拟化,该技术可以绕过常见的纹理大小,数量和视频内存限制,而不会影响质量,性能或大小。 使用Unity 2017,每个纹理最高可达16384 x 16384像素。该技术处理几百张贴图都没有任何问题。 
 
虚拟纹理的工作原理是将所有纹理切割成可管理的图块(或页面),并将它们存储在针对流媒体自定义数据文件中; 在运行时, Amplify Texture始终使用可用的最大分辨率虚拟化纹理,无论是8k或16k纹理(Unity 2017每纹理32k),原始大小永远不会受到影响,虚拟贴图其实就是一张大的图集,中间会生成一张数据索引文件,它存放了图片的索引,大小,针对模型的ID信息等等。根据模型的加载通过索引文件在虚拟贴图上查找对应模型的贴图,将对应的虚拟贴图加载到内存中,将纹理映射到模型上面。 


技术实现参考网址:http://amplify.pt/unity/amplify-texture-2/

关于模型的优化技术差不多就讲完了,运用上面的技术完全可以帮助我们处理密集型建筑模型。下面还有一项重要的技术讲解,也就是我们说的场景裁剪,我们使用的算法也是Occlusion Culling。

Occlusion Culling

Occlusion Culling也是一种遮挡裁剪,可以将遮挡住的物体直接从内存中移除,或者从摄像机可视空间移除,这里讲的算法与Unity自带的Occlusion Culling是不一样的,该算法尤其对建筑物密集的场景非常实用,先看看Occlusion Culling是如何工作的?如下图所示: 
 
在此介绍两种利用Occlusion Culling方法解决遮挡剔除的问题,首先介绍的方法是

Potentially visible set

参考网址:https://en.wikipedia.org/wiki/Potentially_visible_set 
具体实现步骤如下所示: 
1、地图切割成Tile,Tile切割成Portal(视口)和Cell(大物件、中物件、小物件); 
2、检测场景物件所属Cell,一个物件可以属于多个Cell; 
3、 利用蒙特卡洛方法Portal随机一些起点,Cell随机一些终点(根据大、中、小随机不同数量的点); 
4、 双层遍历每个Portal和Cell,射线检测是否阻挡,如果阻挡,判断阻挡物是否被在当前检测Cell内,如果是,Cell可见;(注,当前设置两个高度检测) 
5、 保存检测数据,运行时加载解析,根据玩家位置检测当前Portal,然后遍历场景所有Cell内Item,判断显示和隐藏; 
总之: 
此pvs方案相比于Unity OcclusionCulling,更适合大地图比如5000米x5000米,pvs生成data基于Tile,支持动态加载,占用内存忽略不计,同时CPU消耗也极少;

先看看没有使用Occlusion Culling裁剪算法之前,实现效果图如下所示: 


应用了Occlusion Culling 算法后,看看效果如下所示: 


通过上面两幅图的数据对比,可以看到Draw Call明显减少了,优化效果还是非常明显的,再看看另一种Occlusion Culling 算法实现的效果。

IOC算法

先把该算法能实现的功能给读者介绍一下: 
1、实现建筑物的裁剪 
2、粒子效应遮挡剔除 
3、灯光遮挡剔除 
4、完全支持实时阴影 
5、完全支持动态批处理 
6、支持移动设备上的密集场景处理

我们先看看对特效的遮挡剔除优化,在优化前的场景渲染,如下图所示: 


优化后的遮挡剔除效果,如下图所示: 


通过两幅图对比可以看到,Draw Call减少了一半多,当然我们还可以进一步去优化。

该算法对于密集型建筑同样好用,同样先展示一个没有使用任何裁剪算法的有密集物体的场景,Draw Call数量是非常大的。如下图所示: 

经过我们的Occlusion Culling算法后的裁剪效果,如下图所示: 


Draw Call数量对比也是非常明显的,还是有效果的。

总结:

以上给读者介绍了针对密集型建筑使用的解决方案,该方法在PC端,移动端都是适用的,最后把代码奉上,参考案例代码可以将其应用到自己的项目开发中。

代码下载地址: 
链接:https://pan.baidu.com/s/1Uhp-eejG_7rA_hXz42cBVg 密码:5ehf

参考网址: 
https://blogs.unity3d.com/cn/2018/01/12/unity-labs-autolod-experimenting-with-automatic-performance-improvements/
--------------------- 
作者:海洋_ 
来源:CSDN 
原文:https://blog.csdn.net/jxw167/article/details/82455746 
版权声明:本文为博主原创文章,转载请附上博文链接!

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

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

相关文章

poj 1836 Alignment

题目大意: 给定一排人的身高,求踢出最少的人可以使队列身高如下形状: Description In the army, a platoon is composed by n soldiers. During the morning inspection, the soldiers are aligned in a straight line in front of the capta…

Qt程序崩溃原因

Qt写的程序在执行过程中莫名其妙的出现崩溃,代码没有任何问题。最后发现原因是因为Release版本的程序链接了Debug版的lib文件,所以导致程序执行过程中莫名其妙的出现崩溃。此类错误出现了很多次了,查找起来异常困难,需要注意&…

【转载】jvm内存回收

1.java的内存 java的内存结构分为 堆 (是gc的主要区域) 线程共享,主要是用于分配实例对象和数组 栈 线程私有,它的生命周期和线程相同,又分成 虚拟机栈和本地方法栈,只有它会报 StackOverFlowError,栈深度超标 方法区 线程共享 用于储存被虚拟机加载的类的信息,静态变量 常量和…

2016杭州ccpc

Kingdom of Obsession 标签: 二分图最大匹配2016-10-29 16:23 51人阅读 评论(2) 收藏 举报分类:二分图和最大匹配(2) 版权声明:本文为棒(xian)棒(yu)博主原创文章&#x…

深入理解C语言的函数调用过程

本文主要从进程栈空间的层面复习一下C语言中函数调用的具体过程&#xff0c;以加深对一些基础知识的理解。 先看一个最简单的程序&#xff1a; 点击(此处)折叠或打开 /*test.c*/#include <stdio.h> int foo1(int m,int n,int p){ int x m n p; …

【转载保存】RunTime.getRunTime().addShutdownHook 添加钩子

https://blog.csdn.net/gongxinju/article/details/69963099

Unity3D打包后日志文件输出目录

Unity3D打包后日志文件输出目录&#xff0c;包括日志文件和崩溃时记录文件 C:\Users\Administrator\AppData\LocalLow\长沙迪迈科股份有限公司\镍矿探秘 其中"..\长沙迪迈科股份有限公司\镍矿探秘" 为unity的公司和产品设置

【转载保存】Jsoup使用

https://blog.csdn.net/ricky73999/article/details/54989972

Unity3d LookAt参数说明

Unity3d LookAt参数说明 //// 摘要: // Rotates the transform so the forward vector points at targets current position.//// 参数: // target:// Object to point towards.//// worldUp:// Vector specifying the upward direction.public void LookAt(…

SteamVR导致场景相机不正常

在Unity3D项目中导入SteamVR和VRTK后&#xff0c;有时候会导致非VR场景中的相机运行后异常&#xff0c;姿态和位置不对。 导致的原因可能是&#xff0c;工程设置不对&#xff08;SteamVR和VRTK依赖一些预定义宏&#xff09;&#xff0c;需要将相应的工程设置ProjectSettings文…

【转载保存】java优先队列使用

PriorityBlockingQueue是一个带优先级的阻塞队列,提供了阻塞获取操作。元素按优先级顺序被移除&#xff0c;该队列也没有上限&#xff08;看了一下源码&#xff0c;PriorityBlockingQueue是对 PriorityQueue的再次包装&#xff0c;是基于堆数据结构的&#xff0c;而PriorityQue…

【转载保存】HtmlUnit的使用

信息来源&#xff1a; https://blog.csdn.net/moneyshi/article/details/78799949 https://blog.csdn.net/qq_36176250/article/details/77199595

初入职场的你不应错过的一些书籍

在职场中&#xff0c;听过最接地气的一句话就是&#xff1a;在职场中要眼睛里有活儿&#xff0c;知道什么该说什么不该说&#xff0c;也不要说自己不确定的事情。今天来推荐一些职场老手建议看的书 《好好说话》 有太多人初入职场不会说话&#xff0c;而说话的能力是可以培养的…

关于 Unity WebGL 的探索

转自:https://www.cnblogs.com/yaukey/p/unity_webgl_explore_1.html 查找了 Unity 的官方资料&#xff0c;我们如果需要使用 WebGL 需要面对以下几个挑战&#xff1a; Native Plugin&#xff1a;也就是说各种原生插件&#xff08;C/C等编译的本地机器码库&#xff09;&#…

【转载保存】cookie在登录时的使用

地址:https://blog.csdn.net/df19900725/article/details/78066468?locationNum4&fps1 浏览器按F12点击network中其中一个文件&#xff0c;查看右边信息&#xff0c;把带有Cookie:这种放在addCookie(“Cookie”,“Cookie:”)这种格式

TCP/IP协议详解 卷一(阅读指导)

1. 为了利用网络知识理解服务端网络架构、排查问题、解决问题. 真的没有必要背, wireshark 工具都给你解析的不能再细了。有没有重传&#xff0c;有没有乱序&#xff0c;数据包接收的时间&#xff0c;发送窗口多大&#xff0c;数据有没有拥塞&#xff0c;等等.... 以及协议的解…

Unity脚本生命周期与执行顺序

目录 脚本生命周期 MonoBehavior生命周期图脚本执行顺序 自定义执行顺序 (文章目录) 在Unity中&#xff0c;脚本可以理解为附加在游戏对象上的用于定义游戏对象行为的指令代码。必须绑定在游戏对象上才能开始它的生命周期。游戏对象可以理解为能容纳各种组件的容器&#xff0c…

【转载保存】Java丨jsoup网络爬虫登录得到cookie并带上cookie访问

优秀文章:https://blog.csdn.net/wisdom_maxl/article/details/65631825 jsoup使用cookie&#xff1a; Set<Cookie> cookie_set LoadCSDN.load(); // WebClient wc new WebClient();HashMap<String, String> map new HashMap<String,String>();for (Cook…