Эффективный метод рендеринга кубов с различными текстурами на каждой стороне для игры, подобной Minecraft? - PullRequest
3 голосов
/ 05 февраля 2012

Я пытаюсь решить, какой самый эффективный способ рендерить связку кубов с различными текстурами в игре, подобной Minecraft.

Я обнаружил инстансированный рендеринг .Что я сделал, так это то, что создал единственную «модель куба», в которой хранятся все вершины, нормали и координаты текстуры для куба, из этого я создаю буфер массива и один раз передаю его в графический процессор.Затем я создал массив структур (вектор перевода, индекс текстуры) и использую инстансированный рендеринг, чтобы перерисовывать один и тот же куб снова и снова, каждый раз переводя и с соответствующей текстурой .

Ответы [ 4 ]

6 голосов
/ 06 февраля 2012

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

Стандартное решение (и как это делается в Minecraft) состоит в том, чтобы разделить вашу местность на сектора.Вычислите, какие лица видны, и загрузите их в графический процессор.Когда куб меняется, вам просто нужно заново загрузить его сектор.При рендеринге сектора вы просто рисуете примитивы без каких-либо других вычислений.

Вы можете сделать что-то на основе разреженных октетов вокселов .Это гораздо больше работы, но вы сможете эффективно и точно определить, какие части вашего мира видны.

2 голосов
/ 10 декабря 2013

Я знаю, что этому вопросу уже почти два года, но, возможно, я бы сделал 3D-текстуру, в которой хранятся все отдельные текстуры, где координата текстуры z будет как бы ID блока. С 3D-текстурой вы можете связать сразу все свои отдельные текстуры блоков, что означает, что вы можете использовать рендеринг экземпляров для передачи ваших преобразований вместе с blockID, чтобы получить правильную текстуру блоков для 3D-сэмплера.

1 голос
/ 05 февраля 2012

На моем nVidia 8600M GT я обнаружил, что инстансинг работает лучше всего «в середине» при умеренном числе вершин и количестве экземпляров, но я закончил тем, что создал пару вершин тысячи раз, чтобы исключить избыточные данные вместе с попыткой обновления это.

Я бы выбрал 2 , используя массив текстур вместе с одним экземпляром куба в массиве вершин, и выбрал бы текстуру лица, используя ваши индексы текстур в вашем «массиве экземпляров», где 6 индексы могут быть даже упакованы в несколько целых чисел. Для предоставления атрибутов экземпляров также может быть полезен GL_ARB_instanced_arrays, когда нет необходимости обращаться к буферу с использованием gl_InstanceID (предсказуемо и, следовательно, быстрее в большинстве случаев). Если вам нужно иметь конкретные текстурные координаты экземпляра, я бы связал дополнительный массив координат для каждого экземпляра и текстуры вершины вместе с соответствующим измененным шейдером.

0 голосов
/ 20 января 2015

Действительно поздний ответ, но кто-то обязательно нуждается в нем.

Имейте метод в классе основного блока, который возвращает текстуру с параметром для лица. В отдельных классах, которым требуется несколько текстур, переопределите этот метод и используйте регистр переключения или серию операторов if / else.

Вот как будет выглядеть метод в классе блока:

public int getBlockTexture(int face){
     if(face = top){
         return grass top
     } else if(face = bottom){
         return grass bottom
     } else {
         return grass side
     }
}

Что касается того, как вы используете это в рендерере, возьмите текстуру перед рендерингом каждого лица. Подобно тому, как вы делаете выбраковку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...