威尼斯wns·8885556(vns认证网站)-BinG百科

当前位置:首页 > 新闻资讯 > 技术动向

细数OSG中的“神来之剪”

发布者:威尼斯wns·8885556    时间:2021-01-20 15:14:26


“裁剪”



就是从大量的事务中进行挑选、删除



对一个庞大的三维体而言,往往存在着大量无助于最终渲染结果的对象;将它们从场景中剔除后,将剩余的场景对象发送到OpenGL管线中,即可完成一帧的绘制工作。


这类型的裁剪工作通常称为“可见性裁剪”,即只有真正能够被终端用户看到的对象才会被发送到渲染管线中。




常见de裁剪技术


背面裁剪


当我们观察一个不透明物体时,通常大约有一半的物体表面是看不到的,因此完全可以省去这一半的绘制工作,场景的多边形复杂度也将降低1/2左右。


osg本身提供了如下图的背面裁剪的实现函数:

图片1.png




视椎体裁剪


视椎体裁剪就是将不在视椎体中的物体剔除掉不绘制,而在视椎体内部或与视椎体相交的物体绘制的方法,此举对性能的提升有着巨大的帮助。


通常,物体是不规则的,为了方便,我们用该物体的包围球与当前视锥体进行比较。


如果包围球在视锥体外,那么不需要绘制此包围球所表达的节点及其所有的子节点。如下图所示,红色方块在视锥体外,该方块将被裁剪。


图片2.gif


视锥体裁剪包括近平面裁剪、远平面裁剪以及视锥体侧面裁剪三部分。


下图中setProjectionMatrixAsPerspective中的参数zNear、zFar就是对在osg中对相机的远近裁剪面的设置。


NEAR_PLANE_CULLING是近平面裁剪,将超出近平面范围以外的对象裁剪:

图片3.png




细节裁剪


场景中某些物体对于观察者而言可能是极其微小的,足以忽略不计,此时可以用细节筛选特性将它们剔除。


判断对象是否足够细微,需要用一个像素阈值来决定!


注意,这种筛选可能会剔除一些必要的信息(比如用户在屏幕上绘制了一些点,却发现它们全部被吞噬掉了),因此它是一种通过牺牲质量来换取速度的技术~

图片4.png




遮挡裁剪


判断场景中的物体是否有互相遮挡关系,剔除那些被完全遮挡的对象,保留可见物体。但是,完全的遮挡测试算法往往具有过高的复杂度,需要判断每个场景对象与其他对象的遮挡关系,导致计算带来的开销大于绘制带来的开销,并不实用!


比较常见的方法是定义一种“遮挡板”对象(在osg中使用OccluderNode节点),其形状不固定,并且可以遮挡场景中的其他对象。


少量的遮挡板可以有效的增加场景的裁剪效率,尤其在室内景物的裁剪等场合,使用遮挡板来模拟墙面和门体是再好不过的选择~


在osg中OccluderNode本身并不具备遮挡能力,需要指定一个遮挡面osg::ConvexPlanarOccluder来进行遮挡。

图片5.png




聚集裁剪


这是一种类似于背面筛选的场景筛选方法,但是他可以将多个对象组合起来进行统一的背面筛选,从而加快背面筛选的速度。


其基本原理是使用一种截断圆锥体来包含某组几何体的所有法线方向和所有点。


圆锥的定点位于一个控制点cp,并使用法线n和半角A辅助进行定位。因此对于视点eye如果出现下面的条件:

微信图片_20211019171605.png

则认为视点位于该截断圆锥的背面,应当统一剔除它所包含的多个几何体,如下图所示:

图片6.png


在osg中聚集裁剪相关的类名称为ClusterCullingCallback,使用方法如下图所示:

图片7.png

FreeX 产品微信公众号

威尼斯wns·8885556微信公众号

威尼斯wns·8885556视频号