osgUtil::Simplifier 实践

背景介绍

实践中,需要对较大的 obj 模型(使用 OSG 库生产)进行分割,然后做模型简化。分割简化后的模型再进行其它处理(使用 OSG 库)。

出于对 MeshLab 简化功能的使用经验,最初采用的思路是:通过 vcg 库读取 obj 模型,进行分割并简化后,再将模型数据传递给 osg 做后续处理。然而,vcg 没有所谓场景图的概念,导致它在读取 OSG 库生产的模型时破坏了其隐含的节点组织结构。假设 OSG 生产的模型由 10 个osg::Group组成,那么经过 vcg 处理再传递给 osg,可能就只有一个osg::Group。此外,vcg 不支持同时读入多个 obj 模型,而osgDB::readNodeFiles则可以一次性读取多个 obj 模型并将它们组织到一起。

在持续学习的过程中,发现 osg 自带了一个简化工具:osgUtil::Simplifier。既然有工具,那么就可以直接使用 OSG 读取 obj 模型,然后进行分块简化。

osgUtil::Simplifier

Simplifier本质上是一个节点访问器,使用方式非常简单:

  1. 引入头文件:#include <osgUtil/Simplifier>
  2. 定义简化器对象:osgUtil::Simplifier simplifier(0.5)
  3. 为待简化节点应用 2 中对象:node->accept(simplifier)

根据传入的 sampleRatio 参数不同,Simplifier对某一几何模型表现出两种行为:加密或简化。当参数大于 1.0 时执行加密操作;当参数小于 1.0 时执行简化操作。加密操作几乎可以无限进行,只要硬件能够渲染。而简化操作则有局限性:某些情况下可能无效。

简化器无效

对于一个模型,简化器可能无效。例如,下图中,对右侧的立方体数据应用简化器时无效。

简化器无效的本质原因是:调用了edge->isAdjacentToBoundary()方法以忽略"边界边"。所谓边界边,满足以下条件之一:

  1. 使用该边的三角形数目小于 2;
  2. 组成该边的任一顶点被其它"边界边"使用。

忽略边界边是为了防止过度简化。我们知道,一个立方体有 8 个顶点就足够表示了,如上图中由 MeshLab 导出的模型。对于该模型应用简化器,如果多次简化或者一次性将 sampleRatio 参数设置的足够小,程序会异常退出。而由 OSG 生产的模型使用了 24 个顶点,对其应用简化器是无效的。

如果非要进行简化,可以修改源码,取消"边界边"的判断。但这样带来的后果就是模型视觉质量的显著下降。如下图所示:

节点图元集类型

应用简化器后,节点的图元集类型统一为 DrawElementsUIntPrimitiveType。但实践中发现,部分节点的图元集类型变为 DrawElementsUShortPrimitiveType。这是因为简化完成后还调用了osgUtil::optimizeMesh方法对几何进行优化。

其中,VertexCacheVisitor引起了图元集类型的变化。

参考资料

  1. 工具-简化顶点数量
  2. OsgUtil::Simplifier:简化几何体,提升显示性能和渲染效率)(收费了,呵)
相关推荐
Once_day9 分钟前
C++之《程序员自我修养》读书总结(1)
c语言·开发语言·c++·程序员自我修养
Trouvaille ~19 分钟前
【Linux】TCP Socket编程实战(一):API详解与单连接Echo Server
linux·运维·服务器·网络·c++·tcp/ip·socket
坚果派·白晓明30 分钟前
在鸿蒙设备上快速验证由lycium工具快速交叉编译的C/C++三方库
c语言·c++·harmonyos·鸿蒙·编程语言·openharmony·三方库
小镇敲码人37 分钟前
深入剖析华为CANN框架下的Ops-CV仓库:从入门到实战指南
c++·python·华为·cann
Dragon Wu1 小时前
Spring Security Oauth2.1 授权码模式实现前后端分离的方案
java·spring boot·后端·spring cloud·springboot·springcloud
一个有梦有戏的人1 小时前
Python3基础:进阶基础,筑牢编程底层能力
后端·python
爬山算法1 小时前
Hibernate(88)如何在负载测试中使用Hibernate?
java·后端·hibernate
张张努力变强2 小时前
C++ STL string 类:常用接口 + auto + 范围 for全攻略,字符串操作效率拉满
开发语言·数据结构·c++·算法·stl
独断万古他化2 小时前
【Spring 原理】Bean 的作用域与生命周期
java·后端·spring
小镇敲码人2 小时前
探索CANN框架中TBE仓库:张量加速引擎的优化之道
c++·华为·acl·cann·ops-nn