OpenGL ES Polygon с рендерингом нормалей (обратите внимание на «ES!») - PullRequest
0 голосов
/ 09 января 2010

Хорошо ... представьте, что у меня есть относительно простое тело, которое имеет шесть различных нормалей, но на самом деле имеет около 48 граней (8 граней в каждом направлении), и между гранями есть МНОГО общих вершин. Какой самый эффективный способ сделать это в OpenGL?

Я знаю, что могу поместить вершины в массив, а затем использовать индексный массив для их рендеринга, но я должен продолжать разбивать шаги рендеринга вниз, чтобы изменить нормали (то есть установить нормальные 1 ... рендерить 8 граней .. установить нормальное значение 2 ... отрисовать 8 граней и т. д.) Из-за этого я должен поддерживать массив индексных массивов ... по одному на каждую нормаль! Не хорошо!

Другой способ, которым я могу это сделать, - это использовать отдельные массивы нормалей и вершин (или даже чередовать их), но это означает, что мне нужно иметь отношение один к одному для нормалей к вершинам, и это означает, что нормали будут дублироваться В 8 раз больше, чем нужно! Для чего-то со сферической или даже изогнутой поверхностью все нормальности, скорее всего, различны, но для этого это действительно кажется пустой тратой памяти.

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

Теперь формат файла OBJ позволяет вам точно указать, что ... массив вершин и обычный массив различной длины, а затем, когда вы указываете грань, которую вы визуализируете, вы указываете вершину и нормальный индекс (а также Координаты UV, если вы используете текстуры тоже), что кажется идеальным решением! 48 вершин, но только 8 нормалей, затем пары индексов, определяющих грани фигур. Но я не уверен, как сделать это в OpenGL ES (опять же, обратите внимание на «ES».) В настоящее время я должен «денормализовать» (извините за каламбур SQL там) нормали обратно к 1-к-1 с массив вершин, затем рендер. Просто трата памяти на меня.

Кто-нибудь поможет? Я надеюсь, что я упускаю что-то очень простое здесь.

Mark

1 Ответ

1 голос
/ 09 января 2010

Ты ничего не пропустил.Это то, как работает спецификация, потому что так работает большинство аппаратных средств (иначе ваше совершенное не является совершенным аппаратным).

Я не буду вдаваться в сложности реализации аппаратного обеспечения, которое будет поддерживать массив индексов, но яукажет на одну оптимизацию, которую вы, скорее всего, потеряете: GL потенциально использует один индекс в качестве индекса в кеше пост-вершинного преобразования, чтобы не пришлось повторно преобразовывать вершину на следующей итерации.Вы значительно усложняете эту оптимизацию с помощью набора индексов.

Что касается экономии памяти: в вашем случае вы говорите примерно о кубе с каждым лицом, использующим 4 четырехугольника и 8 треугольников.Итак, мы говорим о 9 * 6 = 54 уникальных вершин.если у вас есть только положение и нормали, то это 54 * 4 * 3 * 2 = 1296 B данных вершин + 2 * 48 * 3 = 288 B данных индекса (при условии 4 байта для базовых типов атрибутов и GLushort для индексов).Итого 1584Б.Это предполагает, что неоптимальный формат данных для позиций и нормалей тоже.Альтернатива составляет примерно 26 * 4 * 3 (pos) + 8 * 4 * 3 (норма) + 2 * 48 * 3 * 2 = 312 + 96 + 576 = 984B.Таким образом, вы сэкономили около 0,5 КБ на этот надуманный случай.Передайте это более экономящим память типам для атрибутов, и вы получите: 648 + 288 = 936 против 156 + 48 + 576 = 780 ... Разница становится незначительной.

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

И последнее, как вы сами заметили, в практических трехмерных мирах (т.е. не в мире коробок) экономия такого механизма будетбыть низким: очень немногие атрибуты могут быть разделены.

...