Источники света

51

Чтобы создать реалистически текстурированные трехмерные объекты, WPF использует модель освещения. Основная идея состоит в том, что к трехмерной сцене добавляется один (или несколько) источников света. Характер освещения объектов зависит от выбранного типа источника света, его положения, направления и интенсивности.

Прежде чем погрузиться в изучение освещения WPF, важно понять, что модель освещения WPF ведет себя не так, как свет в реальном мире. Хотя система освещения WPF и предназначена для того, чтобы эмулировать реальный мир, вычисление правильного отражения — задача, требующая серьезных вычислительных ресурсов. WPF допускает ряд упрощений, гарантирующих практичность модели освещения, даже в случае анимированных трехмерных сцен с несколькими источниками света. К таким упрощениям относятся перечисленные ниже:

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

Даже если не указать источник света, объект будет видимым. Однако без источника света все, что вы увидите — это сплошной черный силуэт.

В WPF предлагаются четыре класса источников света, каждый из которых унаследован от абстрактного класса Light. В рассматриваемом примере мы ограничимся только одним DirectionalLight, который представляет наиболее распространенный тип освещения.

DirectionalLight

Заполняет сцену параллельными лучами света, идущими в указанном направлении

AmbientLight

Наполняет сцену рассеянным светом

PointLight

Свет распространяется во все стороны из точечного источника

SpotLight

Свет распространяется из одной точки по конусу

Вот как можно определить источник белого света DirectionalLight:

<DirectionalLight Color="White" Direction="-1,-1,-1" />

В этом примере вектор, определяющий направление света, начинается в точке начала координат (0,0,0) и продолжается до (-1,-1,-1). Это означает, что каждый луч света представляет собой прямую линию, направленную сверху слева и вниз направо. Это имеет смысл для данного примера, поскольку треугольникповернут под углом к направлению света (как показано на рисунке):

Путь прямого источника света

При вычислении направления света важен угол его падения, а не длина вектора. Это значит, что направление света (-2,-2,-2) эквивалентно нормализованному вектору (-1,-1,-1), поскольку описывает тот же угол.

В данном примере направление источника света не является перпендикулярным к поверхности треугольника. Чтобы добиться такого эффекта, вектор света следует направить точно вниз по оси Z, используя направление (0,0,-1). Но такое направление было бы несколько искусственным. Поскольку лучи света падают на треугольник под углом, его поверхность будет текстурированной, что создает более реалистичный эффект.

Прямой свет иногда сравнивают с солнечным. Причина в том, что лучи света, поступающие от расположенного далеко источника (такого как солнце), становятся почти параллельными. Все объекты, описывающие свет, непрямо наследуются от класса GeometryModel3D. Это значит, что их можно трактовать как трехмерные объекты и помещать внутрь ModelVisual3D, а также добавлять в окно просмотра.

Наряду с DirectionalLight, AmbientLight — еще один универсальный класс, описывающий освещение. Сам по себе AmbientLight дает плоское представление трехмерных фигур, но его можно комбинировать с другим источником света и добавить некоторую подсветку затененных областей. Секрет заключается в применении AmbientLight неполной интенсивности. Вместо использования белого AmbientLight применяйте одну треть от белого (установив свойство Color в #555555) или меньше. Также можно установить свойство DiffuseMaterial.AmbientColor, чтобы управлять тем, насколько сильно AmbientLight будет влиять на материал в заданной сетке.

Использование белого цвета (по умолчанию) дает наиболее сильный эффект, в то время как черный цвет создает впечатление материала, не отражающего рассеянный свет. DirectionalLight и AmbientLight — наиболее часто используемые виды освещения для простых трехмерных сцен. PointLight и SpotLight создают нужный эффект, только когда сетка состоит из огромного числа треугольников — обычно, порядка нескольких тысяч. Это связано с тем, как WPF текстурирует поверхности.

Как уже известно, WPF экономит время на вычислении интенсивности освещения только в вершинах треугольника. Если фигура состоит из небольшого количества треугольников, такое приближение разрушает эффект. Некоторые точки попадут в пределы PointLight и SpotLight, а другие — нет. В результате может получиться, что некоторые треугольники будут освещены, в то время как другие останутся в полной темноте. Вместо получения мягко очерченного круга света на объекте получится группа подсвеченных треугольников, в результате граница света окажется зубчатой.

Проблема в том, что PointLight и SpotLight используются для создания мягких округлых световых эффектов, а для изображения круглой фигуры требуется очень много треугольников. (Чтобы создать идеальный круг, для каждого пикселя, лежащего на периметре круга необходим треугольник.) Если есть сетка, состоящая из сотен или тысяч треугольников, то модель частично освещенных треугольников проще приблизить к кругу и получить желаемый световой эффект.

Пройди тесты
Лучший чат для C# программистов