То, что контролирует лица, - это интерполяция атрибутов.
Существует много различных видов интерполяции, и вы можете проверить их в Спецификации языка шейдинга металлов (https://developer.apple.com/metal/Metal-Shading-Language-Specification.pdf, 4.5 Атрибуты выборки и интерполяции
).
Если вам нужен плоский вид, есть два способа сделать это: вам нужно будет использовать flat
интерполяцию или изменить исходную модель.
Вы можете настроить интерполяцию в коде шейдера. Вам нужно будет украсить входные данные вашего фрагментного шейдера атрибутами для интерполяции.
Если у вас есть направленное освещение или любое другое освещение, чтобы добиться такого плоского вида, ваши нормали должны быть плоскими по всем граням, для этого вы хотите пометить входные данные фрагмента шейдера примерно так:
struct FragmentInput
{
float3 position;
float4 color;
float3 normal [[flat]];
};
Плоская интерполяция будет использовать данные из первой вершины треугольника и использовать их для всего треугольника.
И результат также будет в некоторой степени зависеть от самих исходных данных вершин.
Другой способ - просто иметь вершины, которые принадлежат одному лицу (в вашем случае одно лицо квадратное, состоящее из двух треугольников), имеют одинаковое значение для нормали. Таким образом, ваша модель будет иметь больше вершин (некоторые вершины будут иметь одну и ту же позицию, но они будут принадлежать разным граням). Вы должны быть в состоянии сделать это в любом 3D-редакторе.
Вы можете попробовать и поэкспериментировать с различными типами интерполяции для достижения разного вида.
Спасибо @warrenm за комментарий о провоцировании вершины.