Направленные источники света и точечные источники света — два основных метода освещения в Unity. Эффект света на объекте можно настроить в стандартном шейдере. Но здесь мы пишем собственные шейдеры. Итак, это 4-й из серии статей.

  1. Шейдеры в Unity — Введение
  2. Шейдеры в Unity — Flat Color
  3. Шейдеры в Unity — Ламберт и Эмбиент

В предыдущей статье о диффузном шейдере мы использовали Directional Lights для получения эффекта молнии. Направленные источники света – это источники света, падающие из дальнего света источников, таких как солнце. Направленные световые лучи всегда параллельны друг другу.

Точечные источники света – это источники света, которые находятся близко к объекту. Лучи света распространяются из одной точки во все стороны.

Как и в предыдущей статье, если использовать тот же шейдер для точечного света вместо направленного, то затенение на объекте будет выглядеть неестественно. Необходимо внести некоторые изменения в скрипт шейдера для рендеринга точечных источников света. Пока остановимся на теории.

Мы рассчитали количество света, падающего на объект с направлением света и нормалью.

На изображении свет падает сверху. Интенсивность света в верхней части выше и выпадает при достижении красной линии. Это изменение зависит от нормальи к поверхности и направления света.

Когда угол между нормалью и направлением света увеличивается, интенсивность света, падающего на сферу, уменьшается. Мы называем этот угол Угол падения. Таким образом, точечный продукт нормали и направления света можно использовать для расчета количества света.

количество света = точка (нормаль к поверхности, направление света)

Это векторы. Нам нужно получить единичный вектор для представления направления.

Как сделать поверхность нормальной?

Трехмерные объекты, которые мы создаем с помощью программного обеспечения для моделирования, имеют структуру данных с вершинами и их соединениями. Существует несколько способов представления 3D-модели. Механизм рендеринга получает только вершины, а не поверхности. Вы можете задаться вопросом, почему мы не можем строить поверхности из вершин. Да мы можем. Но для рендеринга может потребоваться больше вычислительной мощности и времени.

В Unity мы имеем дело с нормалями вершин, а не с нормалями поверхностей. Нормали вершин — это усредненные нормали поверхностей, которые связаны с этой вершиной.

Мы рассчитали цвет вершины в шейдерах Lambert и Ambient. Вершина — это просто точка объекта (модели). Цвет необходимо применить ко всем частям объекта. Объект состоит из набора треугольников. Каждый треугольник имеет 3 вершины и три цвета для каждой вершины. Механизм рендеринга интерполирует эти цвета на поверхности треугольника.

Цвет обрабатывается в вершинном шейдере и передается во фрагментный шейдер для сглаживания. Смотрите ниже цифры. Это будет работать для направленного света, но не для точечного.

Направленный свет падает равномерно на одинаковые поверхности. Как и на первом рисунке, точки A и B получают одинаковую интенсивность света от направленного света. Если объект имеет сплошной цвет, поверхность с вершинами A, B получает одинаковую интенсивность цвета с интерполяцией из-за схожей интенсивности в A и B.

Эффект точечного света зависит от его расстояния до объекта. С увеличением расстояния интенсивность света уменьшается. На рисунке с точечным источником света точка E должна иметь наибольшую интенсивность. Но с нашим методом рендеринга мы вычисляем цвета только для C и D, вершин. При интерполяции точка E не получает большей интенсивности. Он получит интерполированное значение из цветов вершин C и D.

Чтобы получить реальный эффект точечного эффекта, куб должен быть намного более детализированным. Это означает, что ему нужно больше вершин. Или мы можем избежать этапов в конвейере рендеринга.

Вершинный шейдер и фрагментный шейдер

Вершинный шейдер отлично подходит для диффузного затенения. Потому что изменение цвета от одной точки к другой не является быстрым. Это даст эффект размытия с чередованием цветов из-за интерполяции.

Предположим, что мы накладываем текстуру на объект. Допустим, это деревянный ящик. Для каждой позиции (пикселя) в поле текстура меняется. При добавлении света молния должна меняться для каждой позиции. С вершинным шейдером у нас есть информация о молнии в вершинах. Чтобы придать реалистичные эффекты, нам нужно уменьшить масштаб до фрагментов. Такие эффекты, как блики, точечные источники света, должны иметь резкость для фотореалистичных изображений. Так что лучше делать световые эффекты, а не базовые диффузные молнии во фрагментном шейдере.