2016-11-08 14 views
0

OSG를 사용하여 점 구름을 렌더링했습니다. 필자는 OSG 요리 책의 예제 인 "draw instancing을 사용한 점군 클라우드 데이터 렌더링"을 예로 들었습니다.이 예제에서는 많은 인스턴스로 한 포인트를 만들고 텍스처를 통해 그래픽 카드에 포인트 위치를 전송하는 방법을 보여줍니다. 그런 다음 셰이더를 사용하여 텍스처에서 포인트를 가져 와서 각 인스턴스를 올바른 위치로 이동합니다. 렌더링되는 것에 두 가지 문제가있는 것으로 보입니다.OSG의 드로잉 인스 턴싱을 사용한 렌더링 포인트 클라우드 데이터 요리 책이 작동하지 않음

첫 번째로, 포인트는 렌더링에 대한보다 직접적인 작업 방식과 비교할 때 올바른 위치에 있지 않습니다. 그들은 제로 오트, 위치에 대한 곱셈 적 요인의 어떤 종류로부터 대략적으로 스케일 된 것처럼 보입니다.

둘째, 이미지가 흐립니다. 포인트는 일반적으로 적절한 위치에있는 경향이 있습니다. 큰 물체가 있어야하는 곳은 많습니다. 그러나, 나는 그 물건이 무엇인지 말할 수 없다. 내 작업 (그러나 느린) 렌더링 방법으로 렌더링 된 데이터는 선명하게 보입니다.

텍스쳐와 드로잉리스트에 동일한 입력 데이터가 들어 있다는 것을 확인 했으므로 두 메소드 모두에서 렌더링과 관련이있는 것처럼 보입니다.

다음은 텍스트 북에서 거의 직접 복사 된 기하학을 설정하는 코드입니다.

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; 
} 

답변

0

실험을 한 번 해보니 OSG Cookbook의 예제 코드에 몇 가지 문제점이 있음을 발견했습니다.

스케일 문제 (첫 번째 문제)가 쉐이더에 있습니다.

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

는 gl_Vertex 행렬 변환과 측근에 추가 한 소자와 3 벡터이므로

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

이것은이어야한다. 그 요소는 항상 1이어야합니다. 예제는 또 다른 3 + 1 벡터를 생성하고 그것을 gl_Vertex에 추가하여 2로 만듭니다. 1을 0으로 바꾸면 스케일 문제가 사라집니다.

흐림 현상 (두 번째 문제점)은 텍스처 보간으로 인한 것입니다.

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); 

너무 보간 단지 점군의 다른 측면에 포인트 일 수있다 인접 텍스처 화소로부터 이들을 보간하는 대신 질감에서 값을 가질 것으로 할 필요가있다. 이 두 가지 문제를 수정 한 후 예제는 광고 된대로 작동하고 제한된 테스트에서 조금 더 빠릅니다.