本文章由cartzhang编写,转载请注明出处。 所有权利保留。 
文章链接:http://blog.csdn.net/cartzhang/article/details/52684127 
作者:cartzhang

一、unity裁剪包括,视锥裁剪和遮挡裁剪。

什么是视锥体裁剪? 
我们来直接看下官方的图解,看图说话。 
场景中的对象: 
https://docs.unity3d.com/uploads/Main/OcclusionNoCulling.png 
 
视锥体的裁剪: 
https://docs.unity3d.com/uploads/Main/OcclusionFrustumCulling.png 

那什么是遮挡裁剪呢? 
https://docs.unity3d.com/uploads/Main/OcclusionFullCulling.png 
 
一图胜千言,这就是遮挡裁剪。 
要说的是,之前的此功能必须是pro版本才有的,现在使用的5.4.0f3版本是有的。 
遮挡裁剪的原理:通过在场景中使用一个虚拟的摄像机来创建一个物体潜在可视性状态(set)的层级. 这些数据可以让每个运行时间内的摄像机来确定什么能看见什么看不见。通过这些数据, Unity 将确定只把可以看见的物体送去渲染. 
使用二叉树进行处理,通过判断是否在相机中可以看到来,把看到的送去渲染。 
当然还可以通过划定一个盒子来确定裁剪空间,更多细节请自行参考官方。 
要说的是:当你使用遮挡剔除时你依然使用视锥体剔除,他们是并行不悖的。

本来有同事,是关于怎么判断对象是否在相机内渲染。 
这个想来简单,找到对象的render,然后判断Renderer.isvisiable即可。 
这时候发现,他说这个没有卵用。那我就自己试试了。 
先写了个扩展方法:

public static class RendererExtensions
{public static bool IsVisibleFrom(this Renderer renderer, Camera camera){Plane[] planes = GeometryUtility.CalculateFrustumPlanes(camera);return GeometryUtility.TestPlanesAABB(planes, renderer.bounds);}
}

但是这个方法很明显只判断是否在视锥平头体内,不判断是否可见。 
那问题就在于遮挡裁剪啊,那看官方也琢磨了很久,一开始总是做不好。下面就是个记录历程,希望对看本文的你有所帮助。 
来吧,实践是检验真理的唯一标准啊。

二、首先搭建一个简单场景。


注意:要把所有的cube转换为静态的,static. 
其中有个小红色块是有代码的。 
脚本如下:


public class IsRenderByCamera : MonoBehaviour
{private Renderer rend;// Use this for initializationvoid Start (){rend = this.GetComponent<Renderer>();}// Update is called once per framevoid Update (){//if (rend.IsVisibleFrom(Camera.main))//{//    Debug.Log("visible by main camera");//}//else//{//    Debug.Log("not visible by any camera");//}//if (rend.IsVisibleFrom(Camera.main)) Debug.Log("Visible");//else Debug.Log("Not visible");if (rend.isVisible){Debug.LogError("red cube is Visible");}else{Debug.LogError("red cube not Visible"); ;}if (Camera.main.useOcclusionCulling){Debug.Log("currrent occluson is using");}    }void OnWillRenderObject(){//Debug.Log("will render ");}void OnBecameVisible(){//Debug.Log("became Visible");}void OnBecameInvisible(){//Debug.Log("became InVisible");}}

直接构建操作如下: 
 
下面就不多说了,直接构建啊。 
构建完毕,看到如下结果: 

发现没有,坐标轴位置就是相机位置,注意有什么特点。 
在场景中直接拽动相机到大的遮挡版之前,发现没有发生任何所想的,所有对象依旧在渲染啊。 

三、这是怎么回事。

查找了各种资料和尝试,相机在大遮挡板之前,遮挡在其后的小块没有一个消失不渲染的。而相机进入到蓝色盒子里面的时候,就可以发现有小块依次的不渲染。 

这个就简单了、 
所以,在相机的后面添加了一个cube,记得也修改为静态的。构建后如下图: 

结果呢: 

真的可以,大功告成啊。

四、是不是全部都需要为静态的呢?

怎么办,继续测试实验啊。

实验一、

就把相机背后点,还有做边界的小块做为静态,其他都非静态。 

当然结果很明显了。没有遮挡版,无法实现遮挡裁剪。

实验二、

将大白板该为静态。 

可以实现对大白板后面对象的遮挡裁剪。 

而超越之后就没有效果了。 

五、注意:

1.若在unity编辑器中没有选中Occlusion,在场景中拖拽相机,并不会出现效果。这个很怀疑是bug. 
顺便说下,测试版本为5.4.0f3。 
2.还有就是必须在Visulize模型下才可以正常使用。 
 
而在Edit模式下,不进行遮挡裁剪。 
 
所以,怀疑Unity的版本只在编辑器下才有效果。写代码就是为打包测试、

六、打包测试

结果是打包后遮挡裁剪是正常的。可以使用。哈哈,嫌疑排除,自己想多了。 
但是怀疑精神还要有的。对吧? 
本来是判断对象是否在相机内渲染做处理的,误入歧途,做了这些工作,分享出来,自己做个记录,以飨读者。

七、工程地址:

Github:https://github.com/cartzhang/OcclusionCullingTest

参考:

https://docs.unity3d.com/Manual/OcclusionCulling.html 
http://bbs.9ria.com/thread-216913-1-1.html

八、—————–2017-03-09更新—–

**当前使用遮罩的时候,需要把它作为主场景,还必须有相机才可以。

若用其他场景来加载此场景,则遮罩不起作用。**

Camera和 tris,verts的优化

Unity的Camera组件有很多可调节的参数,当需要做优化的时候,stats面板中的tris和verts这两个重点项都与Camera组件的参数有很大关系,有些参数的意义Unity手册说得不够详细,经过我们的测试和咨询,把结论记下来,如果有不对欢迎留言~

Field Of View 这个值的范围从1-179,是一个角度,具体是哪个角呢,是从Camera自身坐标系x轴方向看过去的红色夹角,如图所示,在这个角度下摄像机的远近裁剪面与y轴平行

Clipping Planes 远近裁剪面,就是下图中梯形的下底和上底

接下来是本文的重点,请大家仔细阅读,我就一个常见问题,stats面板中显示的GPU渲染的面数tris及顶点数verts到底如何计算出来的?

这个问题之所以常见是因为影响Unity渲染效率或者游戏画面是否卡顿的最关键指标,就是stats面板中的tris和verts,搞清楚这两个指标的确切含义对于优化的意义不言而喻。

之前我一直以为这两个数据就是模型落在camera梯形中的顶点数,后来发现并不是这样,我把远裁剪面弄得与近裁剪面很接近,或者调整 field of view 都会改变这个梯形的体积,里面容纳的顶点看起来没有,但是stats面板里的数据确一直有。如下图,看起来这个梯形里没有顶点但是tris和verts的数据都显示GPU渲染出了那个矩形,12个tris(空场景本身有2个tris,剩下矩形6个4边面等于12个tris三角面)加24个verts(这个数字受多因素影响,不能从表现上解释):

camera 组件参数如下(注意field of view)

当我改变 field of view 到 120 以上时候,在game视图下我们就能看到那个cube了,换句话说,真正的结论就是:

Unity stats 视图中的 tris 和 verts 并不仅仅是视锥中的梯形的 tris 和 verts,而是 field of view 所有取值下的 tris 和 verts,换句话说,哪怕你在当前game视图中看不到这个 cube,如果当你把 field of view 调大到 179 过程中都看不到这个 cube,stats面板才不会统计,gpu才不会渲染,否则,都会渲染(见下图),而且unity不会把模型拆分,这个模型哪怕只有1个顶点需要渲染,unity也会把整个模型都渲出来。

 

Unity 模型优化中很常见的一个问题就是美术用max做出来的模型,在max里显示面数和顶点数少于unity中的,或者出现不一致的情况,根据我们的实际项目经历原因:

1)是max的数据显示的是四边面,而unity里status面板里的面tris是三角面,这两个的对应关系我根据数据总结是三角面的数量是四边面的2倍。

2)大家看一下这篇博主的文章 Unity 与 max 中顶点数面数区别的原因,其中提到的  Unity 这种将顶点一分为多的原因,主要有两个:一个是UV splits,一个是Smoothing splits。我们遇到的主要是 UV split,用通俗的语言解释就是UV 分割(max中用了几张UV网),比如一个人,他的UV分为头,身子两部分,一个车UV分为窗户,轱辘等等,UV分的越多,到Unity中的顶点数就会越多。所以最终的结果就是有的模型面多顶点少(如人物),有的模型面少顶点多(结构复杂的车),这也就解释了为什么max和Unity中模型的面数一般是一致的但是顶点数并没有直接的对应关系。

3)不同的制作方式对模型最终到Unity里也就是GPU的渲染下也会有不一样的结果,下面上一组图,三个不同颜色的加号,因为制作方式的不同导致了截然不同的渲染效率(而且这点往往和美术同学的认识相悖)

以下三个加号,绿的是两个box横竖穿插,红的是一个矩形挤压出横向矩形,黄的是一个竖box加左右两个横向box删掉横向box与纵向重叠的面,具体表现大家看数据吧~

  

Unity Occlusion Culling 遮挡剔除研究相关推荐

  1. Occlusion Culling 遮挡剔除 相机系列5

    Occlusion Culling 遮挡剔除 本文档主要是对Unity官方手册的个人理解与总结(其实以翻译记录为主:>) 仅作为个人学习使用,不得作为商业用途,欢迎转载,并请注明出处. 文章中涉 ...

  2. Unity优化之遮挡剔除Occlusion Culling

    遮挡剔除, 当一个物体被其他物体遮挡住而不在摄像机的可视范围内时不对其进行渲染..遮挡剔除在3D图形计算中并不是自动进行的.因为在绝大多数情况下离 camera 最远的物体首先被渲染,靠近摄像机的物体 ...

  3. Occlusion(遮挡剔除)

    Occlusion 1.视锥体剔除(Frustum Culling) 根据摄像机的视见体的范围对场景模型进行剔除操作,在视见体以外的物体不被渲染,但是在视见体中的物体会以离摄像机最远的物体开始渲染,逐 ...

  4. Unity性能优化-遮挡剔除

    1. Occlusion Culling-遮挡剔除的含义:没有在Camear视野范围内的游戏物体不进行渲染Render(默认情况下,Unity是会渲染所有GameObject,无论Camear是否看得 ...

  5. Culling 渲染剔除

    文章目录 剔除 视锥体frustum裁剪 遮挡剔除 摄像机距离剔除 遮挡剔除 Occlusion Culling 建立遮挡剔除 遮挡剔除窗口 遮挡剔除烘焙 - bake Occlusion Area ...

  6. Unity 3D 遮挡剔除(仅专业版) Occlusion Culling (Pro only)

    分享一下我老师大神的人工智能教程!零基础,通俗易懂!http://blog.csdn.net/jiangjunshow 也欢迎大家转载本篇文章.分享知识,造福人民,实现我们中华民族伟大复兴! Occl ...

  7. Unity - 遮挡剔除(Occlusion Culling)优化

    遮挡剔除对概念   很多童鞋的Unity作品完成后,发现场景卡的要死,尽管在模型阶段采用了很多优化建模方法,但还是卡顿.电脑端都这么卡,发布到移动端就更不用说了.遇到这种情况,很多童鞋急得团团转,不知 ...

  8. Unity3d遮挡剔除(Occlusion Culling)优化【2019】

    遮挡剔除的概念   很多童鞋的Unity作品完成后,发现场景卡的要死,尽管在模型阶段采用了很多优化建模方法,但还是卡顿.电脑端都这么卡,发布到移动端就更不用说了.遇到这种情况,很多童鞋急得团团转,不知 ...

  9. unity学习——遮挡剔除

    unity学习--遮挡剔除 基本概念: "遮挡剔除"过程可防止 Unity 为那些被其他游戏对象完全挡住(遮挡)的游戏对象执行渲染计算. 说白了就是如果摄像机看不见的物体,我就不用 ...

最新文章

  1. python读取配置文件简单封装
  2. 每日一题之 MySQL
  3. s5pv210——I2C的代码实践
  4. Spark调优 数据本地化调优
  5. Entity FrameWork利用Database.SqlQueryT执行存储过程并返回参数
  6. Flash CS6 新功能
  7. JavaScript-switch条件分支语句
  8. 用Python批处理将WORD文件转换成PDF格式(工具:win32com模块)
  9. 密码加密解密(一)——摩斯密码
  10. Spark入门-什么是Spark
  11. rabbitMQ-server控制台安装报错启动失败,黑窗口一闪即过Applying plugin configuration to rabbit .. failed.
  12. 搜狗输入法--自定义短语配置文件
  13. 实现 JSON.parse
  14. 信息安全咨询服务内容
  15. ext winds点击超连接_东南大学崔铁军院士团队在信息超材料领域取得新进展
  16. spring Boot 报错Failed to introspect Class [xxx] from ClassLoader
  17. Pig下载与安装与使用
  18. 量化交易管理则是“定性思想的量化应用”
  19. “饱暖思淫欲”,下一句才是经典,却少有人知
  20. 向360手机卫士学习如何优化android程序性能

热门文章

  1. 多屏显示 全屏后在副显示器_多屏生产力有多重要?联想ThinkVision思逸14显示器...
  2. linux中断处理程序架构,Linux外部中断架构初始化流程-----Tiny6410
  3. 微服务配置中心是干啥的_微服务化改造系列之三:配置中心
  4. 总结better-scroll插件的使用
  5. ❤️Bean的自动装配(详细)
  6. 固定定位小技巧(HTML、CSS)
  7. 实验3-1 求一元二次方程的根 (20 分)
  8. Chrome 谷歌浏览器中文默认小于12px设置无效解决办法
  9. 像excel一样规律填充(三)
  10. 数据库学习--DQL(数据库查询语言)