Теневое отображение или проекция теней — это процесс, посредством которого тени добавляются в 3D компьютерную графику . Эта концепция была введена Лэнсом Уильямсом в 1978 году в статье под названием «Отбрасывание изогнутых теней на изогнутые поверхности». [1] С тех пор она использовалась как в предварительно отрендеренных, так и в реальных сценах во многих консольных и ПК-играх.
Тени создаются путем проверки того, виден ли пиксель из источника света, путем сравнения пикселя с z-буфером [2] или глубинным изображением вида источника света, сохраненным в виде текстуры .
Если вы посмотрите из источника света, все объекты, которые вы можете видеть, будут казаться освещенными. Однако все, что находится за этими объектами, будет в тени. Это основной принцип, используемый для создания карты теней. Вид источника света визуализируется, сохраняя глубину каждой поверхности, которую он видит (карта теней). Затем визуализируется обычная сцена, сравнивая глубину каждой нарисованной точки (как если бы ее видел свет, а не глаз) с этой картой глубины.
Эта техника менее точна, чем объемы теней , но карта теней может быть более быстрой альтернативой в зависимости от того, сколько времени заполнения требуется для той или иной техники в конкретном приложении, и поэтому может быть более подходящей для приложений реального времени. Кроме того, карты теней не требуют использования дополнительного буфера трафарета и могут быть изменены для создания теней с мягким краем. Однако, в отличие от объемов теней, точность карты теней ограничена ее разрешением.
Рендеринг затененной сцены включает два основных этапа рисования. Первый создает саму карту теней, а второй применяет ее к сцене. В зависимости от реализации (и количества источников света) это может потребовать двух или более проходов рисования.
Первый шаг — визуализация сцены с точки зрения источника света. Для точечного источника света вид должен быть перспективной проекцией, ширина которой соответствует желаемому углу воздействия (это будет своего рода квадратный прожектор). Для направленного света (например, от Солнца ) следует использовать ортогональную проекцию .
Из этого рендеринга извлекается и сохраняется буфер глубины. Поскольку важна только информация о глубине, обычно избегают обновления буферов цвета и отключают все расчеты освещения и текстур для этого рендеринга, чтобы сэкономить время отрисовки. Эта карта глубины часто хранится как текстура в графической памяти.
Эту карту глубины необходимо обновлять каждый раз, когда происходят изменения в освещении или объектах сцены, но ее можно использовать повторно в других ситуациях, например, когда движется только камера наблюдения. (Если имеется несколько источников света, для каждого источника света необходимо использовать отдельную карту глубины.)
Во многих реализациях практично визуализировать только подмножество объектов в сцене на карте теней, чтобы сэкономить время, необходимое для перерисовки карты. Кроме того, смещение глубины, которое смещает объекты от света, может быть применено к визуализации карты теней в попытке решить проблемы сшивания , когда значение карты глубины близко к глубине поверхности, которая рисуется (т. е. поверхности, отбрасывающей тень) на следующем этапе. В качестве альтернативы иногда для аналогичного результата используется отбраковка передних граней и визуализация только задней части объектов на карте теней.
Вторым шагом является рисование сцены с обычной точки обзора камеры , применяя карту теней. Этот процесс состоит из трех основных компонентов. Первым шагом является нахождение координат объекта, видимого со стороны света, поскольку 3D- объект использует только 2D- координаты с осями X и Y для представления своей геометрической формы на экране, эти координаты вершин будут совпадать с соответствующими краями частей тени в самой карте теней (карте глубины). Вторым шагом является тест глубины, который сравнивает значения z объекта со значениями z из карты глубины, и, наконец, после завершения, объект должен быть нарисован либо в тени, либо на свету.
Чтобы проверить точку на карте глубины, ее положение в координатах сцены должно быть преобразовано в эквивалентное положение, видимое светом. Это достигается путем умножения матриц . Местоположение объекта на экране определяется обычным преобразованием координат , но для определения местоположения объекта в пространстве света необходимо сгенерировать второй набор координат.
Матрица, используемая для преобразования мировых координат в координаты обзора источника света, та же самая, что использовалась для рендеринга карты теней на первом этапе (в OpenGL это произведение матриц вида модели и проекции). Это создаст набор однородных координат , которым необходимо перспективное деление ( см. 3D-проекция ), чтобы стать нормализованными координатами устройства , в которых каждый компонент ( x , y или z ) попадает в диапазон от −1 до 1 (если он виден из вида источника света). Многие реализации (такие как OpenGL и Direct3D ) требуют дополнительного умножения матриц масштаба и смещения для преобразования этих значений от −1 до 1 в значения от 0 до 1, которые являются более обычными координатами для поиска карты глубины (текстурной карты). Это масштабирование можно выполнить до перспективного деления, и его легко свернуть в предыдущий расчет преобразования, умножив эту матрицу на следующее:
Если это делается с помощью шейдера или другого расширения графического оборудования, это преобразование обычно применяется на уровне вершин, а сгенерированное значение интерполируется между другими вершинами и передается на уровень фрагментов.
После того, как координаты светового пространства найдены, значения x и y обычно соответствуют местоположению в текстуре карты глубины, а значение z соответствует связанной с ним глубине, которую теперь можно проверить по карте глубины.
Если значение z больше значения, сохраненного в карте глубины в соответствующем месте ( x , y ), объект считается находящимся за заслоняющим объектом и должен быть помечен как неудачный , чтобы быть нарисованным в тени процессом рисования. В противном случае он должен быть нарисован освещенным.
Если местоположение ( x , y ) выходит за пределы карты глубины, программист должен решить, должна ли поверхность быть освещена или затенена по умолчанию (обычно освещена).
В реализации шейдера этот тест будет выполняться на уровне фрагмента. Кроме того, необходимо проявлять осторожность при выборе типа хранилища текстурных карт, которое будет использоваться оборудованием: если интерполяция невозможна, тень будет выглядеть с острым, неровным краем (эффект, который можно уменьшить с помощью большего разрешения карты теней).
Можно модифицировать тест карты глубины для создания теней с мягкими краями, используя диапазон значений (в зависимости от близости к краю тени), а не просто «пройдено» или «не пройдено».
Технику теневого картирования можно также модифицировать для рисования текстуры на освещенных областях, имитируя эффект проектора . Картинка выше, озаглавленная «визуализация карты глубины, спроецированной на сцену», является примером такого процесса.
Рисование сцены с тенями может быть выполнено несколькими способами. Если доступны программируемые шейдеры , тест карты глубины может быть выполнен фрагментным шейдером, который просто рисует объект в тени или освещении в зависимости от результата, рисуя сцену за один проход (после начального более раннего прохода для генерации карты теней).
Если шейдеры недоступны, выполнение теста карты глубины обычно должно быть реализовано с помощью некоторого аппаратного расширения (например, GL_ARB_shadow), которое обычно не позволяет выбирать между двумя моделями освещения (освещенное и затененное) и требует большего количества проходов рендеринга:
В примерах изображений в этой статье использовалось расширение OpenGL GL_ARB_shadow_ambient для выполнения процесса создания карты теней в два прохода.
Одним из основных недостатков теневого отображения в реальном времени является то, что размер и глубина теневой карты определяют качество конечных теней. Обычно это проявляется в виде сбоев алиасинга или непрерывности теней. Простой способ обойти это ограничение — увеличить размер теневой карты, но из-за ограничений памяти, вычислительных возможностей или оборудования это не всегда возможно. Для обхода этого ограничения были разработаны широко используемые методы теневого отображения в реальном времени. К ним относятся каскадные теневые карты [3] , трапециевидные теневые карты [4] , перспективные теневые карты светового пространства [5] или параллельно-разделенные теневые карты [6] .
Также примечательно, что сгенерированные тени, даже если они свободны от алиасинга, имеют жесткие края, что не всегда желательно. Для того, чтобы эмулировать мягкие тени реального мира , было разработано несколько решений, либо путем выполнения нескольких поисков на карте теней, генерации геометрии, предназначенной для эмуляции мягких краев, либо путем создания нестандартных карт глубинных теней. Известными примерами этого являются Percentage Closer Filtering, [7] Smoothies, [8] и карты теней Variance. [9]
{{cite journal}}
: Цитировать журнал требует |journal=
( помощь ){{cite journal}}
: Цитировать журнал требует |journal=
( помощь ){{cite journal}}
: Цитировать журнал требует |journal=
( помощь ){{cite journal}}
: Цитировать журнал требует |journal=
( помощь ){{cite journal}}
: Цитировать журнал требует |journal=
( помощь )CS1 maint: несколько имен: список авторов ( ссылка )