View Frustum Culling

article/2025/3/17 5:44:56

作者:i_dovelemon

来源:CSDN

日期:2014 / 10 / 28

主题:View Frustum, Culling



引言


               在前面的一篇文章获取View Frustum的6个面中讲述了如何根据View-Proj矩阵来获取View Frustum在世界坐标系中的6个平面。研究过场景管理的同学就会知道,在将图元数据传入到流水线之前,我们需要对数据进行组织。而场景管理通常就是进行这样的工作,通过场景管理,我们剔除(Culling)那些不在View Frustum中的物体,也就是在显示器中看不到的几何物体。读者可能会问,硬件不也会进行裁剪操作吗?是的,的确会这样。但是裁剪操作是发生在光栅化操作中。也就是说,很多的数据在最后光栅化的时候,被裁剪掉了,但是在前面的光照计算,纹理过程等等操作中都进行了,这明显浪费了资源,让系统做了不需要进行的工作。而今天讲解的View Frustum Culling就是来判断一个物体是否会显示在界面上,如果不显示,那么在应用程序阶段就将它剔除掉,这样就不用浪费资源来进行操作了。更彻底的,读者还可以实现那些被前面物体遮挡的物体剔除的算法。但这不再本文的讨论范围之内。好了,废话不多说,来讲解今天的内容吧!!!



AABB-Plane Intersecting


              进行View Frustum Culling的关键技术在于进行AABB-Plane检测。在前面的文章中,我们获取到了6个平面,如果能够判断一个物体的AABB包围盒完全的在其中一个平面的负半空间中的话,就表明这个物体一定不再View Frustum中。这里,需要理解一个概念,什么是负半空间?

              理论上,一个平面会将空间划分成为两个半空间,平面法向向量所指向的那个空间是正半空间,而另外一个空间被称为负半空间。我们在获取View Frustum一文中,获取的6个平面的法线都是指向View Frustum内部的。这就给我们的剔除提供了基础。所以,问题的关键就在判断一个AABB-Plane的位置情况。

              实现这样的检测,算法非常简单。我们根据要检测的平面法线的方向,在AABB盒上构造一个和这个方向最接近的一个向量,然后判断这个向量与平面的位置关系。看下面的图:

                                                                                        

               图中给出了三种基本的情况,PQ这条向量就是AABB盒上和平面上法线方向最接近的向量。从上图中可以得出下面的结论:

               1.如果P点在平面所划分的正半空间内,那么AABB盒就在平面的正半空间内

               2.如果Q点在平面所划分的负半空间内,那么AABB盒就在平面的负半空间内

               3.如果P点在负半空间内,Q点在正半空间内,那么AABB就与平面相交叉

               这三个结论,很显然通过观察就能够得到。

               有了上面的结论,我们就是要获取PQ这两个点了。如何获取了?它的特征是和平面的法线方向最接近的值。如果我们单独看一个轴向上的情况,比如X轴向上。如图所示,一个平面的法线在X轴上的投影如下:

                                                   

               我们可以看到N在X轴上的投影为N‘,而想要让PQ的方向和N最接近,那么PQ这个向量在X轴向上的投影应该与N’一致,对吧!!!读者仔细观察下就会发现这样的事实。对于其他轴向上,此种事实同样出现。所以,我们的算法就是基于这个事实来给出的。如下是算法获取PQ这个向量的伪代码部分:

<span style="font-family:Microsoft YaHei;">VECTOR3 P, Q;
AABB a ;
Normal n;if(n.x > 0)
{//P.x < Q.x P.x = a.min.x ;Q.x = a.max.x
}
else
{//P.x > Q.xP.x = a.max.x;Q.x = a.min.x ;
}if(n.y > 0)
{//P.y < Q.yP.y = a.min.y ;Q.y = a.max.y;
}
else
{//P.y > Q.yP.y = a.max.y ;Q.y = a.min.y
}if(n.z > 0)
{//P.z < Q.zP.z = a.min.z  ;Q.z = a.max.z ;
}
else
{//P.z > Q.zP.z = a.max.z ;Q.z = a.min.z ;
}</span>

        通过上面的代码,我们就可以得到PQ这个最接近平面法线方向的向量了。在有了这个向量之后,我们将Q点带入平面方程中,得出结果。如果结果为负,那么就表示Q点在平面的负半空间里面,也就是说上面的结论2成立,物体的AABB盒在平面的外面。还记的前面说过,我们获取的View Frustum的平面的正半空间是指向View Frustum内部的,也就是说如果在负半空间中的话,这个AABB盒就在View Frustum的外面了,不需要在对其他的面进行判断,我们就可以断定这个物体将不会被显示,能够被剔除掉。

        好了,算法就介绍到这里。下面来看下完整的实现如何。



Demo


        下面是测试这个算法的Demo。如果Cube还在View Frustuml里面的时候,就会在屏幕上写出Inside字样,如果在外面就会写出Outside字样。下面是算法的完整显示,同时给出了获取View Frustum的代码:

<span style="font-family:Microsoft YaHei;">void CubeDemo::draw()
{drawCube();//save the view proj matrixm_ViewProj = m_Camera.viewproj();//get the planeD3DXVECTOR4 col0(m_ViewProj._11, m_ViewProj._21, m_ViewProj._31, m_ViewProj._41);D3DXVECTOR4 col1(m_ViewProj._12, m_ViewProj._22, m_ViewProj._32, m_ViewProj._42);D3DXVECTOR4 col2(m_ViewProj._13, m_ViewProj._23, m_ViewProj._33, m_ViewProj._43);D3DXVECTOR4 col3(m_ViewProj._14, m_ViewProj._24, m_ViewProj._34, m_ViewProj._44);m_Plane[0] = (D3DXPLANE)col2 ;m_Plane[1] = (D3DXPLANE)(col3 - col2);m_Plane[2] = (D3DXPLANE)(col3 + col0);m_Plane[3] = (D3DXPLANE)(col3 - col0);m_Plane[4] = (D3DXPLANE)(col3 - col1);m_Plane[5] = (D3DXPLANE)(col3 + col1);for(UINT i = 0 ; i < 6 ; i ++)D3DXPlaneNormalize(&m_Plane[i], &m_Plane[i]);D3DXVECTOR3 vcMin(-5,-5,-5),    // AABB盒的minvcMax(5,5,5),           // AABB盒的max_vcMin, _vcMax ;                // _vcMin ==> P , _vcMax ==> Qbool bOutSide = false ;for(UINT i = 0 ; i < 6 ; i ++){if(m_Plane[i].a > 0){_vcMax.x = vcMax.x ;_vcMin.x = vcMin.x ;}else{_vcMin.x = vcMax.x ;_vcMax.x = vcMin.x ;}if(m_Plane[i].b > 0){_vcMax.y = vcMax.y ;_vcMin.y = vcMin.y ;}else{_vcMin.y = vcMax.y ;_vcMax.y = vcMin.y ;}if(m_Plane[i].c > 0){_vcMax.z = vcMax.z ;_vcMin.z = vcMin.z ;}else{_vcMin.z = vcMax.z ;_vcMax.z = vcMin.z ;}if(D3DXVec3Dot(&D3DXVECTOR3(m_Plane[i].a, m_Plane[i].b, m_Plane[i].c), &_vcMax) + m_Plane[i].d < 0){bOutSide = true ;break ;}}RECT rect ;rect.left = 10.0f;rect.top = 400.0f;rect.right = 100;rect.bottom = 600 ;if(bOutSide){HR(m_pFont->DrawTextA(0, "OutSide", -1, &rect, DT_NOCLIP, D3DCOLOR_XRGB(0,0,0))) ;}else{HR(m_pFont->DrawTextA(0, "Not OutSide", -1, &rect, DT_NOCLIP, D3DCOLOR_XRGB(0,0,0)));}}</span>
               下面是程序截图:

                

                    


               好了,今天到这里结束了!欢迎继续关注我的博客!!!


http://chatgpt.dhexx.cn/article/OUn4smXU.shtml

相关文章

《Frustum PointNets for 3D Object Detection from RGB-D Data》中文翻译

用于从RGB-D数据进行3D物体检测的Frustum PointNets 摘要&#xff1a; 在这项工作中&#xff0c;我们研究了室内和室外场景中RGB-D数据的三维物体检测。 虽然以前的方法专注于图像或3D体素&#xff0c;通常模糊自然3D图案和3D数据的不变性&#xff0c;但我们通过弹出RGB-D扫…

3D目标检测算法详解_pointnet, pointnet++,frustum-pointnets,VoteNet

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文链接&#xff1a; https://blog.csdn.net/ygfrancois/article/details/89853854 知识点回顾 什么是点云&#xff0c;如何获得点云。 点云包…

【unity】性能优化之——视锥体剔除(Frustum Culling)(一)

一.应用背景 在现代游戏中&#xff0c;游戏资源越来越多&#xff0c;游戏场景也越来越大越来越复杂&#xff0c;虽说硬件设备更新迭代很快&#xff0c;性能也日渐强大&#xff0c;但这还远不能缓解复杂繁多的资源带来的性能压力&#xff0c;因而性能优化仍然很有必要。场景资源…

[Unity]Screen position out of view frustum 的解决方法之一

Screen position out of view frustum 最近在开发项目的时候&#xff0c;本来想把预览摄像机的视觉范围扩大一些&#xff0c;故而调整了一下Sence框的摄像机设置&#xff1a; 但是不久就出现了这个问题&#xff1a; 网上出现的大部分是因为Main Camera的 Viewport Rect的 X …

Screen position out of view frustum——steamVR2.7.3 解决方法

最近用了新版steamVR2.7.3&#xff0c;如果只在场景中放置CameraRig,发现出现了以下如图错误&#xff1a; “Screen position out of view frustum (screen pos 0.000000, 0.000000, 1000.000000) (Camera rect 0 0 2384 2648) UnityEngine.GUIUtility:ProcessEvent(Int32, Int…

frustum pointnet代码使用

按照frustum pointnet的github&#xff0c;步骤依次实现 Q1:编译最开始的3个文件说没有tensorflow里没有op.h 解&#xff1a;因为我是用的在conda环境下的tensorflow&#xff0c;所以要把每一个对应tf路径改成自己的路径 原版的tf_interpolate_compile.sh(很遗憾&#xff0c…

点云网络的论文理解(七)-Frustum PointNets for 3D Object Detection from RGB-D Data

名词解释 RGB&#xff1a;就是彩色图像。 RGB-D:就是彩色图像外加一个深度&#xff0c;这个深度就是摄像头到那个东西的距离。 单目RGB-D:就是一个摄像头采集RGB-D数据 双目RGB-D:就是两个摄像头一起采集RGB-D数据&#xff0c;这样类似于两个眼睛的效果&#xff0c;可以更加…

untiy报错: Screen position out of view frustum解决办法

原文链接&#xff1a;https://jingyan.baidu.com/article/19192ad8081c13e53f57077a.html 解决办法1&#xff1a;摄像机的Tag由Main Camera改成Untagged。出现“Screen position out of view frustum (screen pos 256.000000, 0.000000, 15298.202148) (Camera rect 0 0 256 25…

Frustum PointNets for 3D Object Detection from RGB-D Data

Frustum PointNets for 3D Object Detection from RGB-D Data 1.背景 3D的运用以及逐渐广泛&#xff0c;但是之前大多数的工作是将3D书转化为2D的数据或者对3D数据进行体素化处理&#xff0c;这样就失去了3D数据的一些空间特征以及其他的特性。 参考之前2D的工作&#xff0c;…

翻译-Frustum PointNets for 3D Object Detection from RGB-D Data

Frustum PointNets for 3D Object Detection from RGB-D Data 摘要介绍相关工作从RGB-D数据中检测三维物体基于前视图图像的方法&#xff1a;基于鸟瞰图的方法:基于3D的方法: 点云的深度学习 问题定义三维检测与截锥体PointNets截锥体提出3d 语义分割三维实例分割PointNet 规范…

Screen position out of view frustum

Screen position out of view frustum (screen pos 1155.000000, 650.000000, 5000.000000) (Camera rect 0 0 1155 650) unity 在使用的时候报错如上。 前提&#xff1a;Projection:Perspective 原因分析&#xff1a;切割面最近和最远的值误差太大&#xff0c;一般不超过10…

【3D目标检测】Frustum PointNets

《Frustum PointNets for 3D Object Detection from RGB-D Data》论文笔记 一、论文思路二、模型介绍2.1 模型结构2.2 实现细节2.2.1 Frustum Proposal2.2.2 3D Instance Segmentation2.2.3 Amodal 3D Box Estimation2.2.4 模型结构2.2.5 损失函数 三、实验结果 代码 论文 一、…

【3D目标检测】Frustum PointNets for 3D Object Detection from RGB-D Data

目录 概述细节网络结构视锥候选框3D实例分割边界框参数回归损失函数 概述 首先本文是基于图像和点云的&#xff0c;属于早期的模态融合的成果&#xff0c;是串行的算法&#xff0c;而非并行的&#xff0c;更多的是考虑如何根据图像和点云这两个模态的数据进行3D目标检测。 提出…

frustum-pointnets复现过程+遇到的问题+解决方法

frustum-pointnets复现过程遇到的问题解决方法 系统Ubuntu16.04 1.下载KITTI数据集&#xff1a; 并按照README中的格式解压并重组数据集&#xff1a; 2.运行环境配置&#xff1a; 在复现KPConv的环境&#xff08;‘python3’&#xff09;下继续&#xff0c;首先安装一些包&a…

视锥体剔除(Frustum Culling)算法详解-透视投影矩阵直接推导

前言 本文章介绍了如何从投影矩阵&#xff08;ProjectionMatrix&#xff09;推导&#xff0c;得到视锥体&#xff08;Frustum&#xff09;的六个面的面方程&#xff0c;并且判断一个**点&#xff08;point&#xff09;是否在视锥体范围内&#xff0c;或者包围球&#xff08;Bo…

OpenGL中frustum投影矩阵的推导

OpenGL中&#xff0c;有一个函数叫frustum&#xff0c;字面的意思是截锥体&#xff0c;也就是一个去掉头部的锥体&#xff0c;如下图所示&#xff0c; 看了一下《计算机图形学》&#xff08;英文名Computer Graphics with OpenGL&#xff09;的透视投影推导过程&#xff0c;比较…

UE Gameplay入门51(相机视锥空间的计算方法推导)

非常感谢匿名大哥一直对我的支持&#xff0c;本文内容由他赞助 #1. 视锥&#xff08;Frustum&#xff09;是什么 在相机的近裁剪面和远裁剪面之间的渲染范围内的空间叫做视锥空间&#xff08;Frustum&#xff09;&#xff0c;通常情况下我们是不需要处理&#xff0c;但 当下比…

怎样用计算机才能更快,如何让网速变快,详细教您怎么让电脑网速变快

电脑的用户会遇到网速变慢的情况&#xff0c;不足为奇&#xff0c;其原因是多方面的&#xff0c;必须逐一进行解决。不过对于新手来说&#xff0c;该方法将不可取。别依赖技术人员&#xff0c;那么怎么让电脑网速变快&#xff1f;下面&#xff0c;小编跟大家介绍让电脑网速变快…

台式计算机运行慢怎么样能提高速度,如何提高电脑的运行速度,让电脑快起来!...

原标题&#xff1a;如何提高电脑的运行速度&#xff0c;让电脑快起来&#xff01; 本人的笔记本电脑的已经使用了5年多了&#xff0c;经常出现卡顿&#xff0c;运行速度非常慢的情况&#xff0c;有时速度慢到无法忍受。以下是总结的解决电脑运行慢的几个方法&#xff0c;让自己…

电脑速度变快优化

1.加快系统启动速度  WindowsXP的启动速度比Windows2000要快30%左右&#xff0c;但相对于Windows98仍然要慢了不少&#xff0c;不过&#xff0c;我们可以通过优化设置&#xff0c;来大大提高WindowsXP的启动速度。加快系统启动速度主要有以下方法&#xff1a;尽量减少系统在启…