2015-10-16 3 views
1

У меня есть большое количество объектов (не менее 10 000 частиц), таких как треугольники, квадраты, круги или сферы. На самом деле теперь у меня есть один объект, который я делаю много раз. Это выглядит следующим образом: функцияКак визуализировать большое количество подобных объектов?

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

Draw для моего объекта Circle выглядит следующим образом, где переменная «VP» является продуктом проекции матрицы на вид матрицы:

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 для рендеринга похожих объектов?

ответ

2
  1. Фактор из привязки и отстегивания шейдеров. Привяжите шейдер один раз, нарисуйте все, что использует этот шейдер, а затем отвяжите его. Группируйте объекты с помощью шейдеров. Если у вас более сложная материальная система, вы захотите нарисовать все с одинаковыми свойствами материала сразу (например, формы, такие как текстуры и компоненты освещения). Пока вы на нем, оставьте привязанные атрибуты вершин и только выключите их, когда закончите. Все это сводит к минимуму количество вызовов OpenGL, которые вы выполняете.

  2. Если вы можете, установите свою геометрию в VBO оптимального размера (который может отличаться на вашем GPU). Я подозреваю, что вы можете последовательно упаковать все свои фигуры в один буфер, а затем использовать смещение, чтобы выбрать, какой из них нужно рисовать. Это сэкономит вам переключатель VBO.

  3. Если вы собираетесь рисовать одно и то же много раз, считают instanced rendering

  4. Если вы собираетесь рисовать много вещей, много раз, сгруппировать их в партии, как тип.

  5. Если вы пытаетесь создать систему частиц, изучите GPU particle system. Атрибуты частиц, такие как положение и скорость, сохраняются в текстурах, а затем фрагментарные шейдеры обновляют эти атрибуты один раз за призыв на призыв. После того, как они были обновлены, длинный список индексов ((u, v)) передается в виде данных вершин, который используется для индексации текстур частиц для извлечения данных.Затем каждая частица превращается в треугольники или квадратики в геометрическом шейдере и, наконец, отображается на экран.

+0

Система частиц звучит неплохо, но моя модель более сложная система. Моя модель жидкая, и я использую CUDA для обновления состояний частиц. Я могу собрать все свои фигуры в один VBO. В этом случае я могу установить матрицу модели для каждой фигуры? Или каждая вершина VBO будет иметь относительное положение от центра системы? Варианты 1 и 3-4 выглядят как выбор того, что я ищу. –

1

Обычно с любым вопросом оптимизации, первое, что нужно установить, - это место узкого места. Оптимизация на стороне процессора бесполезна, если узким местом является сложность шейдера. Однако, поскольку вы упоминаете 10000 обратных вызовов, которые довольно чрезмерны, я собираюсь просто предположить, что вы связаны с процессором.

Таким образом, основной приоритет будет заключаться в сокращении количества вызовов для розыгрыша. На данный момент вы, кажется, достигаете 10000 частиц с 10000 обратными вызовами.

Обычно, когда я делаю систему частиц, все мои частицы отображаются в виде экранных квадрантов (рекламных щитов) с текстурой, применяемой с использованием одного текстурного атласа, и я бы поставил задачу отобразить все 10000 частиц за один вызов рисования ,

Вы описываете несколько более сложный сценарий; треугольники, квадраты и круги могут быть собраны вместе в одном списке индексированных треугольников, хотя, возможно, вам стоит рассмотреть возможность применения ваших кругов как текстурированного квадрата вместо множества треугольников.

Сфера немного отличается, хотя это относительно сложный объект с высоким полигоном. Если он действительно не может быть смоделирован как рекламный щит, то, возможно, вам лучше изучить инстинктивные методы, чтобы сразу рисовать все сферы.

+0

Мои шейдеры очень простые. Например, это вершинный шейдер: 'void main() {gl_Position = MVP * vec4 (vertexPosition_modelspace, 1.0);}'. Я думаю, что пакетная обработка может помочь мне решить мою проблему. –

Смежные вопросы