Я вижу несколько общих подходов к затенению cel:
- Дублирование и увеличение модели с перевернутыми нормалями (не вариант для меня)
- Фильтр Собеля / фрагментный шейдер подходит к обнаружению края
- Трафаретный буфер подходит к обнаружению края
- Геометрические (или вершинные) шейдерные подходы, которые вычисляют грани и грани нормали
Правильно ли я считаю, что геометрический подход дает наибольший контроль над освещением и толщиной линии, например. для местности, где вы можете увидеть линию силуэта холма, постепенно сливающегося в равнину?
Что если мне не нужно пиксельное освещение на поверхностях моей местности? (И я, вероятно, не буду, поскольку я планирую использовать основанное на ячейке освещение / затенение на основе вершин или текстурной карты.) Тогда мне было бы лучше придерживаться подхода типа геометрии, или вместо этого пойти на подходе экранного пространства / фрагмента чтобы все было проще? Если так, то как бы получить «чернила» холмов внутри силуэта сетки, а не только контур всей сетки (без «чернильных» деталей внутри этого контура? (AKA наводит на мысль о контурах , складках ).
Наконец, возможно ли дешево эмулировать подход с перевернутыми нормалями, используя геометрический шейдер? Меня беспокоит то, что я могу точно продублировать каждую вершину и масштабировать их соответствующим образом, но как бы я подошел к переворачиванию нормалей и отдельной окраске в фрагментном шейдере?
Что я хочу - переменная толщина линий с навязчивыми линиями внутри силуэта ...
Чего я не хочу ...
РЕДАКТИРОВАТЬ: Дальнейшие исследования обнаружили следующее ...
Поскольку у меня огромное количество вершин на местности, даже с учетом LoD на основе расстояния, ни подходы с перевернутыми нормалями, ни подход на основе геометрических шейдеров (даже с отбраковкой усеченного конуса) не были бы разумным вариантом из-за сложной вычислительной сложности, связанной с дублированием и масштабированием всех объектов. загруженные вершины.
Принимая во внимание, что мне не нужно освещение на пиксель в виде сплошного затенения на поверхностях местности, также становится менее разумным рассматривать любые подходы на основе нормалей к лицу - иначе требование для правильного освещения поверхности - так как они естественно, довольно дорого рассчитать. Однако верно то, что они дают наилучшую степень контроля; например, возможность затенять края с помощью «художественных» штрихов: красиво, но, опять же, не очень реально для чрезвычайно сложной игровой среды.
Я бы предпочел избегать трафаретных буферов, так как предпочел бы выполнять всю работу в шейдерах. (Приведенный выше пример с красным контуром был сделан с помощью трафаретного буфера - старая школа.)
Это оставляет фрагменты шейдерных изображений-пространственных подходов. Сложность вычислений сводится к количеству фрагментов, а не к числу вершин (в моем случае это в 10-100 раз меньше операций, чем нужно было бы делать в геометрическом шейдере). Для этого требуется более одного прохода рендеринга, чтобы сгенерировать g-буфер (состоящий из обычного буфера и, возможно, буфера глубины), к которому мы можем применить фильтры разрывов (например, оператор Собеля). Глубина прерывистости - это то, что позволяет наводить контуры и складки. Единственное, что я могу сказать при таком подходе, - это невозможность обеспечить более точное управление шириной краев, хотя при использовании правильного алгоритма в фрагментном шейдере я уверен, что это возможно.
Таким образом, теперь вопрос становится более конкретным: как именно я получу переменную ширину ребер, особенно для внешнего силуэта, в фрагментном шейдере?