GlDrawElements и плоское затенение

Можно ли добиться плоского затенения в OpenGL при использовании glDrawElements для рисования объектов, и если да, то как? Идеальный способ - рассчитать нормальный для каждого треугольника только один раз, если это возможно.

Решение должно использовать только программируемый конвейер (основной профиль).

Ответ 1

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

Я вижу два решения, которые дадут вам постоянное значение для нормали над каждым треугольником:

  • объявить ввод как flat в вашем шейдере и выбрать, какая вершина дает его значение через glProvokingVertex; быстро, но вы получите нормальное значение для одной вершины как нормальное для всего треугольника, которое может выглядеть неправильно.
  • используйте геометрический шейдер, берущий треугольники и выводящий треугольники, чтобы вычислить один нормальный на лице. Это самый гибкий способ, позволяющий вам управлять полученным эффектом, но это может быть медленным (и, возможно, необходимым аппаратным обеспечением для шейдера).

Ответ 2

К сожалению, единственный способ сделать это - дублировать все ваши вершины, поскольку атрибуты являются per-vertex, а не per-triangle

Когда вы думаете об этом, это то, что мы сделали в непосредственном режиме...