如何渲染大量相似的对象? [英] How to render large number of similar objects?

查看:69
本文介绍了如何渲染大量相似的对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有很多物体(至少1万个粒子),例如三角形,正方形,圆形或球形.实际上,现在我有一个对象,可以多次渲染.看起来像这样:

I have large number of objects (at least 10 000 particles) like triangles, squares, circles or spheres. Actually now I have one object which I render many times. It's looks like this:

for (int i=0; i<totalParticleCount; i++) {
    drawObject->pos = hState[i].pos;
    drawObject->draw(vp);
}

我的Circle对象的绘制函数如下所示,其中变量"vp"是视图矩阵上投影矩阵的乘积:

Draw function for my Circle object looks like this where variable "vp" is product of projection matrix on view matrix:

void Circle::draw(const glm::mat4 &vp) {
    glUseProgram(programId);
    glUniformMatrix4fv(matrixId, 1, GL_FALSE, &(vp * getModelMatrix(pos, scale))[0][0]);

    glEnableVertexAttribArray(0);
    glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, (void*)0);

    glDrawArrays(GL_TRIANGLE_FAN, 0, vertexNumber);
    glDisableVertexAttribArray(0);
}

我发现我的渲染过程太慢了.如何提高渲染性能?如何有效地使用opengl渲染相似的对象?

I found that my process of rendering too slow. How can I increase performance of rendering? How can I efficiently use opengl for rendering similar objects?

推荐答案

  1. 将着色器绑定和取消绑定.绑定一次着色器,绘制使用该着色器的所有内容,然后取消绑定.通过着色器对对象进行分组.如果您使用的是更复杂的材质系统,则需要一次绘制具有相同材质属性的所有内容(例如,纹理和照明组件之类的制服).当您使用它时,请保持顶点属性的绑定,并仅在完成后将其关闭.所有这些都最大程度地减少了您进行的OpenGL调用的次数.

  1. Factor out the shader binding and unbinding. Bind the shader once, draw everything that uses that shader, and then unbind it. Group your objects by shader. If you have a more complicated material system, you'll want to draw everything with the same material properties at once (e.g. uniforms like texture and lighting components). While you're at it, leave the vertex attributes bound and only turn them off when you're done. All of this minimizes the number of OpenGL calls you do.

如果可以,将几何图形打包到最佳大小的VBO中(随GPU的不同而不同).我怀疑您可以将所有形状依次打包到一个缓冲区中,然后使用偏移量选择要绘制的形状.这样可以为您节省VBO开关.

If you can, pack your geometry into optimally-sized VBOs (which should vary by your GPU). I suspect you can pack all of your shapes sequentially into one buffer and then use an offset to pick which one to draw. This will save you a VBO switch.

如果要多次绘制相同的东西,请考虑已实例化渲染

If you're going to be drawing the same thing lots of times, consider instanced rendering

如果要多次绘制很多东西,请将它们分组为类似类型的批处理.

If you're going to be drawing a lot of things a lot of times, group them into batches of like type.

如果要创建粒子系统,请考虑制作 GPU粒子系统.诸如位置和速度之类的粒子属性被存储在纹理中,然后片段着色器在每次绘制调用时都会更新这些属性.在更新它们之后,将一长串索引((u,v)坐标)作为顶点数据传入,该索引用于索引粒子纹理以检索数据.然后,在几何着色器中将每个粒子变成三角形或四边形,最后渲染到屏幕上.

If you're trying to make a particle system, look into making a GPU particle system. Particle attributes like position and velocity get stored in textures, and then fragment shaders update those attributes once per draw call. After they have been updated, a long list of indices ((u,v) coordinates) is passed in as vertex data, which is used to index into the particle textures to retrieve the data. Each particle is then turned into triangles or quads in the geometry shader, and finally rendered to the screen.

这篇关于如何渲染大量相似的对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆