本文章由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 initialization
void Start ()
{
rend = this.GetComponent<Renderer>();
} // Update is called once per frame
void 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

——————THE————————————————END——————–



若有问题,请随时联系!!!

非常感谢!!!

Unity Occlusion Culling 遮挡剔除研究的更多相关文章

  1. Occlusion Culling遮挡剔除理解设置和地形优化应用

    这里使用的是unity5.5版本 具体解释网上都有,就不多说了,这里主要说明怎么使用,以及参数设置和实际注意点 在大场景地形的优化上,但也不是随便烘焙就能降低帧率的,必须结合实际情况来考虑,当然还有透 ...

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

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

  3. Unity4.3 遮挡剔除:基本知识

    http://blogs.unity3d.com/2013/12/02/occlusion-culling-in-unity-4-3-the-basics/ 这篇博文由Umbra Software的J ...

  4. 遮挡剔除 Occlusion Culling(转)

    一.首先介绍下draw call(这个东西越少你的游戏跑的越快): 在游戏中每一个被展示的独立的部分都被放在了一个特别的包中,我们称之为“描绘指令”(draw call),然后这个包传递到3D部分在屏 ...

  5. Unity3D-游戏场景优化之遮挡剔除(Occlusion Culling)的使用

    在大型3D游戏场景中,如何优化游戏性能是非常重要的一步.一般遮挡剔除是非常常用的.接下来我们看看如何使用遮挡剔除. 假设这是一个游戏场景. 下面这是相机的视口,相机的视觉是看不到很大立方体后面的那些小 ...

  6. unity 的视锥剔除和遮挡剔除

    Regular frustum culling only renders objects within the camera’s view. This is automatic and always ...

  7. Occlusion Culling

    遮挡剔除 http://www.bjbkws.com/online/1092/ unity遮挡剔除(应用) http://www.unitymanual.com/thread-37302-1-1.ht ...

  8. [WebGL入门]十九,遮挡剔除和深度測试

    注:文章译自http://wgld.org/,原作者杉本雅広(doxas),文章中假设有我的额外说明,我会加上[lufy:],另外.鄙人webgl研究还不够深入,一些专业词语,假设翻译有误.欢迎大家指 ...

  9. Hierarchical Z-Buffer Occlusion Culling

    While I was at GDC I had the pleasure of attending the Rendering with Conviction talk by Stephen Hil ...

随机推荐

  1. js从入门到精通到深入到就业

    本篇博客是我参看人家代码做的总结,个人感觉非常非常好,简单.步步深入,不用花大量时间来学完正本js,只需要把其中的代码理解透彻,上班无压力(上班无压力是指js部分,包括查看框架源代码都有很大帮助) / ...

  2. SINAMICS S120屏蔽报警

    通用的报警屏蔽方法: P2118 = 需要屏蔽的报警号 P2119 = 屏蔽的方式

  3. java 网络流 TCP/UDP

    一.ServerSocket java.lang.Object |-java.net.ServerSocket 有子类SSLServerSocket. 此类实现服务器套接字.服务器套接字等待请求通过网 ...

  4. 859. Buddy Strings (wrong 4 times so many cases to test and consider) if else**

    Given two strings A and B of lowercase letters, return true if and only if we can swap two letters i ...

  5. python--requests库 安装及简单使用

    官方文档:http://www.python-requests.org/en/master/ 1 安装requests库 2 get请求不带参数的 带参数的 3 post请求   更多使用请看官方文档 ...

  6. IOS 设置颜色的的详情

    - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typica ...

  7. Android(java)学习笔记63:Clock App 编写报错01

    1. 首先我们二话不说直接先看报错内容如下: 07-12 08:25:03.572: E/dalvikvm(3602): native fork pid:0 done. 07-12 08:25:03. ...

  8. 课程设计__继承与派生,重载<<

    ///继承与派生 #include <iostream> using namespace std; class Point { public: Point (,):x(a),y(b) {} ...

  9. C++STL之vector向量容器

    vector向量容器   vector向量容器不但能向数组一样对元素进行随机访问, 还能在尾部插入元素 vector具有内存自动管理的功能, 对于元素的插入和删除, 可动态调整所占的内存空间 vect ...

  10. P1316 丢瓶盖

    题目描述 陶陶是个贪玩的孩子,他在地上丢了A个瓶盖,为了简化问题,我们可以当作这A个瓶盖丢在一条直线上,现在他想从这些瓶盖里找出B个,使得距离最近的2个距离最大,他想知道,最大可以到多少呢? 输入输出 ...