osg的点云lod技术预研
大数据量点云显示的技术绝对是各个行业急需解决的问题,也是一款点云软件是否具有竞争力不可或缺的条件,像开源的CloudCompare软件也在近两年加入了LOD技术(基于OpenGL),这样大数据量点云的显示不在成为困扰显示引擎的绊脚石。国内激光点云软件的领跑者lidar360也率先在利用osg的lod技术实现了该项技术,目前博主也在自己默默的专研该项技术,博主对那些利用opengl来实现lod技术的开发团队表示由衷的钦佩,同时也感慨这些开发团队强大的创造力。OSG的强大之处在于其对于LOD技术进行了高度封装,就好像你给外行用一句概括LOD是什么一样,OSG的仅仅以简单的几句代码就实现了该过程,可不可以理解osg的出现就是为了能把OpenGL用简单易懂的话去概括呢。
当然由于博主研究osg技术,还有其他方面的难题没有解决,对于点云的lod显示技术,其实还有十分重要的一步得实现,也是必须得实现的,不然lod依旧是一个梦,那就是对数据建立索引,大家可以想象,随着鼠标滚轮的滑动,随着视点远近变化然后来显示与之相应的数据块,所以每次显示仅仅是所有点云的一部分,所以显示引擎的压力大大减小。目前PCL提供了强大的octree技术,当然具体怎么去实现,笔者还需要进一步去摸索,今天的博客仅仅是给大家提供一个具体的思路。让LOD技术不再神秘,
其实博主第一次在所里听到这个技术的时候,感觉就像是那种世界级的科研难题,当时所有的“学者”好像都在提这个技术,但是具体是什么好像却没人能说的清,又想起小时候课本上坐井观天的故事了;“失业后”,点云的lod技术目前基本处于烂大街的情况了,只是看谁优化的更好而已。
来一个形象的例子:
点云的索引构建我会继续研究的。
来一个osg的例子:
来上一段能运行的代码:
#include <osgViewer/Viewer> #include <osgViewer/ViewerEventHandlers> #include <osg/Node> #include <osg/Geode> #include <osg/Geometry> #include <osgDB/ReaderWriter> #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osgGA/StateSetManipulator> #include <osgUtil/Optimizer> #include <osgUtil/DelaunayTriangulator> #include <osgUtil/DelaunayTriangulator> //创建视图所需头 #include <osgDB/Registry> #include <osgDB/ReadFile> #include <osgDB/ReaderWriter> #include <osgDB/WriteFile> #include <osg/Node> #include <osgViewer/Viewer> #include <osgDB/ReadFile> #include <osgDB/WriteFile> #include <osg/ShapeDrawable> #include <osg/Geode> #include <osgGA/StateSetManipulator> int main() { osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer(); //这里还是给显示进行一下初始化来看看 { viewer->getCamera()->setClearColor(osg::Vec4(1, 1, 0.3, 0)); osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits; traits->x = 40; traits->y = 40; traits->width = 600; traits->height = 480; traits->windowDecoration = true; traits->doubleBuffer = true; traits->sharedContext = 0; osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get()); osg::ref_ptr<osg::Camera> camera = new osg::Camera; camera->setGraphicsContext(gc.get()); camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height)); GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT; camera->setDrawBuffer(buffer); camera->setReadBuffer(buffer); // add this slave camera to the viewer, with a shift left of the projection matrix viewer->addSlave(camera.get()); } osg::ref_ptr<osg::Group> root = new osg::Group(); osg::ref_ptr<osg::Geode> geode = new osg::Geode(); osg::ref_ptr<osg::TessellationHints> hints = new osg::TessellationHints; hints->setDetailRatio(0.05);//设置精细度 geode->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0, 0.0, 0.0), 100.0), hints.get())); osg::ref_ptr<osg::Geode> geode2 = new osg::Geode(); osg::ref_ptr<osg::TessellationHints> hints2 = new osg::TessellationHints; hints2->setDetailRatio(0.5); geode2->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0, 0.0, 0.0), 100.0), hints2.get())); osg::ref_ptr<osg::Geode> geode3 = new osg::Geode(); osg::ref_ptr<osg::TessellationHints> hint3 = new osg::TessellationHints; hint3->setDetailRatio(10); geode3->addDrawable(new osg::ShapeDrawable(new osg::Sphere(osg::Vec3(0.0, 0.0, 0.0), 100.0), hint3.get())); osg::ref_ptr<osg::LOD> lod = new osg::LOD; lod->addChild(geode, 300, 400); lod->addChild(geode2, 400, 600); lod->addChild(geode3, 600, 5000); lod->setCenter(osg::Vec3(0.0, 0.0, 0.0)); root->addChild(lod); viewer->setSceneData(root.get()); viewer->addEventHandler(new osgGA::StateSetManipulator(viewer->getCamera()->getOrCreateStateSet())); return viewer->run(); }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具