【问题标题】:How to draw a terrain model efficiently from Esri Grid (osg)?如何从 Esri Grid (osg) 有效地绘制地形模型?
【发布时间】:2020-10-27 12:58:25
【问题描述】:

我有许多 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=false

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

【问题讨论】:

标签: c++ opengl 3d rendering openscenegraph


【解决方案1】:

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

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

【讨论】:

  • 感谢您的提示,我愿意接受所有有价值的选择。很抱歉,我找不到任何关于“右场追踪”的文档,是否有一些我可以查找的参考资料?此外,我对如何“预先计算四叉树和有符号距离函数并根据高度场进行追踪”有点迷茫,当然我错过了一些基础知识。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多