gpt4 book ai didi

c++ - 使用来自 OSG Cookbook 的绘图实例渲染点云数据不起作用

转载 作者:行者123 更新时间:2023-11-28 05:26:14 35 4
gpt4 key购买 nike

我正在使用 OSG 渲染点云。我遵循了 OSG 说明书中标题为“使用绘制实例渲染点云数据”的示例,该示例展示了如何使用多个实例制作一个点,然后通过纹理将点位置传输到显卡。然后它使用着色器将点从纹理中拉出并将每个实例移动到正确的位置。渲染的内容似乎有两个问题。

首先,与更直接、有效的渲染方法相比,这些点的位置不正确。看起来它们是粗略地从零开始缩放的,这是位置上的某种乘法因子。

其次,图像模糊。点通常在正确的位置;一个大物体应该在的地方有很多点。但是,我不能说出对象是什么。使用我的工作(但速度较慢)渲染方法渲染的数据看起来很清晰。

我已经验证我在两种方法中都有相同的输入数据进入纹理和绘制列表,所以看起来它必须与渲染有关。

下面是设置Geometry的代码,几乎是直接从课本上抄来的。

osg::Geometry* geo = new osg::Geometry;

osg::ref_ptr<osg::Image> img = new osg::Image;
img->allocateImage(w,h, 1, GL_RGBA, GL_FLOAT);

osg::BoundingBox box;
float* data = (float*)img->data();
for (unsigned long int k=0; k<NPoints; k++)
{
*(data++) = cloud->x[k];
*(data++) = cloud->y[k];
*(data++) = cloud->z[k];
*(data++) = cloud->meta[0][k];
box.expandBy(cloud->x[k],cloud->y[k],cloud->z[k]);
}

geo->setUseDisplayList(false);
geo->setUseVertexBufferObjects(true);
geo->setVertexArray( new osg::Vec3Array(1));
geo->addPrimitiveSet( new osg::DrawArrays(GL_POINTS, 0, 1, stop) );
geo->setInitialBound(box);

osg::ref_ptr<osg::Texture2D> tex = new osg::Texture2D;
tex->setImage( img);
tex->setInternalFormat( GL_RGBA32F_ARB );
tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);

这是着色器代码。

void main () {
float row;
row = float(gl_InstanceID) / float(width);
vec2 uv = vec2( fract(row), floor(row) / float(height) );
vec4 texValue = texture2D(defaultTex,uv);
vec4 pos = gl_Vertex + vec4(texValue.xyz, 1.0);
gl_Position = gl_ModelViewProjectionMatrix * pos;
}

最佳答案

经过大量试验,我发现OSG Cookbook 中的示例代码存在一些问题。

缩放问题(第一个问题)在着色器中。

vec4 pos = gl_Vertex + vec4(texValue.xyz, 1.0);

应该是

vec4 pos = gl_Vertex + vec4(texValue.xyz, 0.0);

这是因为 gl_Vertex 是一个 3 vector ,带有一个额外的 1 元素来辅助矩阵转换。该元素应始终为 1。该示例创建了另一个 3+1 vector 并将其添加到 gl_Vertex 使其成为 2。将 1 替换为零,比例问题就消失了。

模糊(第二个问题)是由纹理插值引起的。

tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::LINEAR);
tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::LINEAR);

需要

tex->setFilter( osg::Texture2D::MIN_FILTER, osg::Texture2D::NEAREST);
tex->setFilter( osg::Texture2D::MAG_FILTER, osg::Texture2D::NEAREST);

这样插值器将只从纹理中获取值,而不是从可能是点云另一侧的点的相邻纹理像素中插值它们。解决这两个问题后,该示例如宣传的那样工作,并且在我的有限测试中似乎更快一些。

关于c++ - 使用来自 OSG Cookbook 的绘图实例渲染点云数据不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40494374/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com