Как определить ориентацию геометрической поверхности в Scenekit - PullRequest
0 голосов
/ 15 декабря 2018

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

vec4 normal = vec4(_surface.normal, 1.0);

// Assume value is [-1, 1], scale to [0, 1]
float color = normal.z * 0.5 + 0.5;

_surface.diffuse = vec4(color, color, color, 1.0);

. Похоже, что normal.z относительно камеры (или вида).Я предполагаю, что мне нужно преобразовать значение, чтобы оно находилось в другом месте.Я пробовал несколько преобразований (и комбинаций преобразований), таких как u_inverseViewTransform, но результаты все, похоже, находятся в поле зрения.Кто-нибудь знает, как раскрасить геометрию, основываясь на ориентации ее поверхностей?

1 Ответ

0 голосов
/ 16 декабря 2018

Так как _surface.normal - это вектор в пространстве вида, вам необходимо преобразовать вектор в мировое пространство.

Преобразование мирового пространства точечной формы в пространство просмотра выполняется с помощью u_viewTransform, поэтомуОбратная операция (из пространства обзора в мировое пространство) может быть выполнена с помощью u_inverseViewTransform.

_surface.normal - вектор направления, но не точка.Вектор должен быть преобразован нормальной матрицей, которая является транспонированной, обратной к верхней левой матрице 3 * 3 матрицы 4 * 4:

transpose(inverse(mat3(u_viewTransform)))

См. Почему транспонированная обратнаяматрицы представления модели, используемой для преобразования векторов нормалей? , Зачем преобразовывать нормали с помощью транспонирования инверсии матрицы просмотра моделей?

Но так как u_viewTransform и u_inverseViewTransform are Ортогональные матрицы транспонированная, обратная может быть пропущена, поскольку обратная матрица и транспонированная матрица равны.См. . В каких случаях обратная матрица равна транспонированию? .

Далее следует преобразовать с помощью mat3(u_inverseViewTransform):

vec3 normal = mat3(u_inverseViewTransform) * _surface.normal;

float color = normal.z * 0.5 + 0.5;

_surface.diffuse = vec4(color, color, color, 1.0);
...