Я работаю над небольшой игрой, использующей webgl. В этой игре у меня есть какой-то лес, который состоит из множества (более 100) деревьев. Поскольку у меня есть только несколько разных моделей дерева, я поворачиваю и масштабирую эти модели по-разному, прежде чем отобразить их.
В данный момент я перебираю все деревья, чтобы показать их:
for (var tree in trees) {
tree.display();
}
В то время как display()
метод дерева выглядит так:
display : function() { // tree
this.treeModel.setRotation(this.rotation);
this.treeModel.setScale(this.scale);
this.treeModel.setPosition(this.position);
this.treeModel.display();
}
Многие древовидные объекты имеют один и тот же объект treeModel
, поэтому мне приходится устанавливать поворот / масштаб / положение модели каждый раз, прежде чем отобразить ее. Значения поворота / масштаба / положения различны для каждого дерева.
Метод отображения treeModel
делает все необходимое:
display : function() { // treeModel
// bind texture
// set uniforms for projection/modelview matrix based on rotation/scale/position
// bind buffers
// drawArrays
}
Все модели деревьев используют один и тот же шейдер, но могут использовать разные текстуры.
Поскольку модель одного дерева состоит только из нескольких треугольников, я хочу объединить все деревья в одно VBO и отобразить весь лес одним вызовом drawArrays()
.
Некоторые предположения, облегчающие разговор о числах:
- Есть 250 деревьев для отображения
- Есть 5 разных моделей дерева
- Каждая модель дерева имеет 50 треугольников
У меня есть вопросы:
На данный момент у меня есть 5 буферов размером 50 * 3 * 8 (position + normal + texCoord) * floatSize
байт. Когда я хочу отобразить все деревья с одним vbo, у меня будет буфер с размером 250 * 50 * 3 * 8 * floatSize
байт. Я думаю, что не могу использовать индексный буфер, потому что у меня разные значения положения для каждого дерева (вычисленные из значения положения модели дерева и положения / масштаба / поворота дерева). Это правильно, или я все еще могу использовать индексные буферы, чтобы хотя бы немного уменьшить размер буфера? Может быть, есть другие способы оптимизировать это?
Как обрабатывать различные текстуры моделей деревьев? Я могу привязать все текстуры к разным текстурным блокам, но как я могу определить в шейдере, какую текстуру следует использовать для фрагмента, который отображается в данный момент?
Когда я хочу добавить новое дерево (или любой другой объект) в этот буфер во время выполнения: нужно ли создавать новый буфер и копировать содержимое? Я думаю, что новые значения не могут быть добавлены с помощью glMapBuffer
. Это правильно?