首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >具有细节级别的OpenGL实例呈现

具有细节级别的OpenGL实例呈现
EN

Computer Graphics用户
提问于 2016-06-27 15:05:43
回答 1查看 1.6K关注 0票数 5

问题:我试图用许多(大约10000)个相似的物体来画一个场景(在我的例子中,灌木丛,但可能是任何东西)。对于每一个灌木,我有三个网格,有一个不同数量的三角形,我想使用这些网格中的一个取决于距离相机。

第一种方法:我可以选择正确的网格在CPU上,更新模型矩阵后,每灌木,然后绘制与正确的网格VBO。问题是我需要每帧更新10000次模型矩阵.您可以猜到这意味着性能方面的问题。

第二种方法:在CPU上再次选择正确的网格,但这一次使用实例渲染在一次绘制调用中绘制所有具有最低lod的灌木,然后是中间lod的灌木,然后是高lod的灌木丛。我已经在GPU上储存了灌木丛的位置。但我在这里的问题是,我仍然需要发送一个数组作为统一变量,其中包含必须在哪个位置绘制网格的信息。通过这种方法,我遇到了统一变量的极限。

问题:我想做的是计算从灌木丛到GPU摄像机的距离(例如,在顶点着色器中没有问题)。然后,根据结果,只绘制具有正确细节级别的VBO。因此,我的问题是,是否有可能选择哪个VBO来使用GPU (我不认为有任何可能这样做,因为在顶点和片段着色器,我是一个已经很远的管道)?或者你还有什么我可以尝试的想法?

最好的,艾伯特

EN

回答 1

Computer Graphics用户

回答已采纳

发布于 2016-06-27 19:28:07

海事组织,你的第二种方法的一个变体将是最简单的,而且可能相当快。

你分析过什么了吗?一个CPU应该极快地咀嚼10000矩阵乘法。如果您想获得更高的性能,可以使用SIMD /线程更新。也就是说,最慢的部分可能是在PCIE总线上发送10000块矩阵的带宽。

但是,再说一遍,这都是假设。试一试,然后分析一下。

我在想这样的事情:

(我为DX的功能道歉。我不太熟悉相应的OpenGL函数。也就是说,OpenGL应该是非常相似的)

代码语言:javascript
复制
// Variable definitions

vector<matrix> lod0;
vector<matrix> lod1;
vector<matrix> lod2;

ID3D11Buffer lod0VertexBuffer;
uint lod0VertexCount;

ID3D11Buffer lod1VertexBuffer;
uint lod1VertexCount;

ID3D11Buffer lod2VertexBuffer;
uint lod2VertexCount;

ID3D11Buffer instanceBuffer;

/// ..................


/// Per frame...
lod0.clear();
lod1.clear();
lod2.clear();

for (uint i = 0; i < bushes.size(); ++i) {
    float distance = distance(bushes[i].pos, camera.origin);
    if (distance < 50.0f) {
        lod0.push_back(bushes[i].matrix);
    } else if (distance < 100.0f) {
        lod1.push_back(bushes[i].matrix);
    } else {
        lod2.push_back(bushes[i].matrix);
    }
}

D3D11_MAPPED_SUBRESOURCE mappedResource;
ID3D11Buffer vertexBuffers[] = {
    lod0VertexBuffer,
    instanceBuffer
};

// Update lod0 matrices
context->Map(instanceBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
memcpy(mappedResource.pData, &lod0[0], sizeof(matrix) * lod0.size());
context->Unmap(instanceBuffer, 0);

// Draw lod0
context->IASetVertexBuffers(0, 2, vertexBuffers, nullptr, nullptr);
context->DrawInstanced(lod0VertexCount, lod0.size(), 0, 0);


// Update lod1 matrices
context->Map(instanceBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
memcpy(mappedResource.pData, &lod1[0], sizeof(matrix) * lod1.size());
context->Unmap(instanceBuffer, 0);

// Draw lod1
vertexBuffers[0] = lod1VertexBuffer;
context->IASetVertexBuffers(0, 2, vertexBuffers, nullptr, nullptr);
context->DrawInstanced(lod1VertexCount, lod1.size(), 0, 0);


// Update lod2 matrices
context->Map(instanceBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource);
memcpy(mappedResource.pData, &lod2[0], sizeof(matrix) * lod1.size());
context->Unmap(instanceBuffer, 0);

// Draw lod2
vertexBuffers[0] = lod2VertexBuffer;
context->IASetVertexBuffers(0, 2, vertexBuffers, nullptr, nullptr);
context->DrawInstanced(lod1VertexCount, lod2.size(), 0, 0);

如果结果太慢,您可以尝试在计算着色器中进行此计算,然后使用间接绘图调用绘制结果。见AZDO

票数 1
EN
页面原文内容由Computer Graphics提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://computergraphics.stackexchange.com/questions/3688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档