OSG之细节层次节点

440 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 23 天

1 细节层次节点

细节层次节点(osg::LOD)继承自osg::Group。使用细节层次节点可以实现不同层次下物体的渲染。细节层次(Level of Detail,LOD)的基本思想是使用物体的一种简单形式表达物体,这样可以使绘制的图形尽量简洁。

当视点靠近物体时,用详细的细节表示;当视点远离物体时,用简化模型来表示。由于距离原因,简化后的模型与细节详细的模型看上去很接近,这样就可以获得一个比较好的加速效果。在后面的章节中还会讲到粒子系统中的雾效,可以与LOD一起使用,当一个物体进入不透明的雾化区域时,可以完全不用绘制这个物体。

此外,还可以使用雾化机制实现时间临界绘制,通过将远平面移近,可以对物体进行提前裁剪,这样可以取得比较快的绘制速度,从而提高帧率。

在OSG中,对于一个LOD模型,它是一次性载入内存的,而且只是有选择地绘制渲染。osg::LOD的继承关系图如下图所示。

2.png

LOD计算的是视点到物体包围盒中心的距离,在应用程序中也可以改变这种方式,它有两种中心模式。LOD的切换同样是根据距离来确定的,应用程序中同样可以根据屏幕像素大小来切换,它也有两种变换模式。

enum CenterMode

{

USE_BOUNDING_SPHERE_CENTER, //包围盒中心

USER_DEFINED_CENTER //自定义中心,需要自己调用 setCenter()

}

enum RangeMode

{

DISTANCE_FROM_EYE_POINT, //距视点的距离

PIXEL_SIZE_ON_SCREEN //屏幕像素的大小

}

2 细节层次节点示例

细节层次节点(osg::LOD)示例代码如下所示。

#include <osgViewer/Viewer>

#include <osg/Node>
#include <osg/Geode>
#include <osg/Group>
#include <osg/LOD>

#include <osgDB/ReadFile>
#include <osgDB/WriteFile>

#include <osgUtil/Optimizer>

#include "utility.h"

int main()
{
	// 创建Viewer对象,场景浏览器
	osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();

	// 创建场景组根节点
	osg::ref_ptr<osg::Group> root = new osg::Group();

	// 创建一个节点,读取牛模型
	osg::ref_ptr<osg::Node> node1 = osgDB::readNodeFile(GetCurrentPath() + "\\Data\\cow.osg");

	// 创建一个节点,读取滑翔机模型
	osg::ref_ptr<osg::Node> node2 = osgDB::readNodeFile(GetCurrentPath() + "\\Data\\glider.osg");

	// 创建一个细节层次LOD节点
	osg::ref_ptr<osg::LOD> lod = new osg::LOD();

	// 添加子节点,在0-30显示牛
	lod->addChild(node1.get(), 0.0f, 30.0f);

	// 添加子节点,在30-100范围内显示滑翔机
	lod->addChild(node2.get(), 30.0f, 100.0f);

	// 写入lod.osg文件
	osgDB::writeNodeFile(*(lod.get()), GetCurrentPath() + "\\Data\\lod.osg");

	// 添加到场景
	root->addChild(lod.get());

	// 优化场景数据
	osgUtil::Optimizer optimizer;
	optimizer.optimize(root.get());

	// 设置窗口大小
	setWindowSize(viewer.get(), 600, 400, "Lod");

	// 设置场景数据
	viewer->setSceneData(root.get());
	// 初始化并创建窗口
	viewer->realize();
	// 开始渲染
	viewer->run();

	return 0;
}

效果图

3.png

动态效果图

1.gif

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 23 天