首页 > 解决方案 > 如何从 Esri Grid (osg) 有效地绘制地形模型?

问题描述

我有许多 Esri Grid 文件 ( https://en.wikipedia.org/wiki/Esri_grid#ASCII ),我想在不损失精度的情况下以 3D 渲染它们,我正在使用 OpenSceneGraph。

问题是这个网格大约是 1000x1000(或更多)点,所以当我提取顶点,然后计算三角形以创建几何图形时,我最终拥有数百万个它们并且与场景的交互是不可能的(帧速率下降到0)。

我尝试了几种方法:

  1. 三角列表

    基本上,当我读取文件时,我用每个三角形 3 个顶点填充一个数组(这会导致重复);

osg::ref_ptr<osg::Geode> l_pGeodeSurface = new osg::Geode;
osg::ref_ptr<osg::Geometry> l_pGeometrySurface = new osg::Geometry;
osg::ref_ptr<osg::Vec3Array> l_pvTrianglePoints = osg::Vec3Array;
osg::ref_ptr<osg::Vec3Array> l_pvOriginalPoints = osg::Vec3Array;

... // Read the file and fill l_pvOriginalPoints 

for(*triangle inside the file*)
{
   ... // Compute correct triangle indices (l_iP1, l_iP2, l_iP3)

    // Push triangle vertices inside the array
    l_pvTrianglePoints->push_back(l_pvOriginalPoints->at(l_iP1));
    l_pvTrianglePoints->push_back(l_pvOriginalPoints->at(l_iP2));
    l_pvTrianglePoints->push_back(l_pvOriginalPoints->at(l_iP3));
}

l_pGeometrySurface->setVertexArray(l_pvTrianglePoints);
l_pGeometrySurface->addPrimitiveSet(new osg::DrawArrays(GL_TRIANGLES, 0, 3, l_pvTrianglePoints->size()));
  1. 索引三角形列表

    和以前一样,但是数组只包含每个顶点一次,我创建了第二个索引数组(基本上我告诉 osg 如何构建三角形,没有重复)

osg::ref_ptr<osg::Geode> l_pGeodeSurface = new osg::Geode;
osg::ref_ptr<osg::Geometry> l_pGeometrySurface = new osg::Geometry;
osg::ref_ptr<osg::DrawElementsUInt> l_pIndices = new osg::DrawElementsUInt(osg::PrimitiveSet::TRIANGLES, *number of indices*);
osg::ref_ptr<osg::Vec3Array> l_pvOriginalPoints = osg::Vec3Array;

... // Read the file and fill l_pvOriginalPoints 

for(i = 0; i < *number of indices*; i++)
{
   ... // Compute correct triangle indices (l_iP1, l_iP2, l_iP3)

    // Push vertices indices inside the array
    l_pIndices->at(i) = l_iP1;
    l_pIndices->at(i+1) = l_iP2;
    l_pIndices->at(i+2) = l_iP3;
}

l_pGeometrySurface->setVertexArray(l_pvOriginalPoints );
l_pGeometrySurface->addPrimitiveSet(l_pIndices.get());

三角形列表与三角形索引

  1. 实例化

    这是一个实验,因为我从未使用过着色器,我认为我可以实例化一个三角形,然后使用变换矩阵在我的场景中的每个三角形的顶点着色器中操纵它的坐标(将矩阵作为统一传递数组,一个用于三角形)。我最终得到了太多的制服,只有一个 20x20 的网格。

    我使用这些链接作为参考:

    https://learnopengl.com/Advanced-OpenGL/Instancing ,

    https://books.google.it/books?id=x_RkEBIJeFQC&pg=PT265&lpg=PT265&dq=osg+instanced+geometry&source=bl&ots=M8ii8zn8w7&sig=ACfU3U0_92Z5EGCyOgbfGweny4KIUfqU8w&hl=en&sa=X&ved=2ahUKEwj-7JD0nq7qAhUXxMQBHcLaAiUQ6AEwAnoECAkQAQ#v=onepage&q=osg%20instanced%20geometry&f=错误的

以上都没有解决我的问题,我还能尝试什么?我在渲染技术方面是否遗漏了什么?我认为这是相当简单的任务,但我有点卡住了。

标签: c++opengl3drenderingopenscenegraph

解决方案


我觉得你应该考虑退后一步。如果您正在可视化基于 GIS 的地形数据,osgEarth 确实是为此而设计的,并且为大型地形提供了相当有效的 LOD 工具。您是否需要始终以最大全 LOD 表示的数据,或者您是否正在寻找动态 LOD 以提高帧速率?

根据您的目标和要求,您可能希望查看一些更高级的地形渲染技术,例如右场追踪等。如果地形始终是静态的,您可以预先计算四叉树和有符号距离函数并根据高度场进行追踪。


推荐阅读