netlib.narod.ru | < Назад | Оглавление | Далее > |
Перед тем, как мы начнем воссоздавать все обсужденные ранее эффекты расширенного динамического диапазона, давайте взглянем на несколько базовых тем, которые пригодятся нам в дальнейшем. Эти темы включают использование текстур с плавающей точкой и управление экспозицией.
Главная причина введения новых текстур с плавающей точкой заключается в обеспечении поддержки возможностей, требующих более широкий диапазон значений и точность, чем те, которые предоставляются обычными восьмиразрядными текстурами. Визуализация в расширенном динамическом диапазоне это первый пример области, где могут использоваться такие текстуры с высоким разрешением.
Текстуры с плавающей точкой существуют в двух видах. Фактически, вы можете выбирать использовать ли 16-разрядные или 32-разрядные текстуры. Хотя 32 разряда обеспечивают большее разрешение, для них также требуется в два раза больше памяти и соответствующая пропускная способность шины. Для вас все это означает, что цветовые компоненты в текстуре с плавающей точкой представлены способом, позволяющим использовать любое числовое значение. Поскольку для HDR не требуется такого широкого диапазона, в этой главе для цели визуализации будет использоваться 16-разрядный формат, а именно A16R16G16B16.
Поскольку текстуры с плавающей точкой идеально подходят для визуализации в расширенном динамическом диапазоне, имеет смысл познакомиться с базовыми техниками, используемыми при работе с ними. Если ваша видеокарта не поддерживает такие текстуры, можно использовать программную эмуляцию. Позднее в этой главе вы увидите, как можно использовать обычные целочисленные текстуры для имитации некоторых эффектов.
Первая вещь, которую следует учесть при работе с расширенным динамическим диапазоном, это управление экспозицией. И человеческому глазу и камере необходим механизм, позволяющий приспосабливаться к различным условиям освещения. Вы же не хотите, чтобы внешние сцены были залиты слепящим светом, а внутренние — полностью погружены во тьму. Именно поэтому, например, ирисовая оболочка человеческого глаза подстраивается под различное освещение.
При визуализации в расширенном динамическом диапазоне вам необходим подобный механизм для управления средней интенсивностью освещения в вашей сцене. Данный механизм обычно называется управлением экспозицией. Представленный здесь базовый шейдер включает стандартную сцену с фоном и чайником, а также компоненты, необходимые для поддержки управления экспозицией.
Поскольку нам необходим простой шейдер с окружающей средой и объектом, мы начнем с использования шаблона шейдера shader_1.rfx, разработанного в главе 7. Первый шаг для подготовки этого шейдера к HDR — увеличение яркости сцены. В текущем примере мы добавим HDR-информацию к карте окружения.
Идеальным решением было бы преобразование или создание окружения в виде текстуры с плавающей точкой, содержащей полную информацию о яркости сцены. Хотя это выполнимо, на данный момент доступно немного программ, способных выполнить такую задачу. Более простое решение заключается в применении текущей карты окружения и использовании ее альфа-канала в качестве масштабного множителя яркости. Нулевое значение альфа соответствует наименьшему уровню яркости, а 1 — это максимальная интенсивность. Затем вы используете эти значения из альфа-канала при визуализации для умножения на цветовые компоненты, чтобы создать более широкий диапазон цветов, чем доступен обычно.
Используя графические редакторы, такие как Adobe Photoshop, вы можете добавить альфа-значения к вашей карте окружения, чтобы более ярким объектам, таким как солнце, соответствовали большие значения в альфа-канале. На рис. 8.2 показана карта окружения, совмещенная с альфа-каналом для HDR.
Рис. 8.2. Цветовой и альфа-каналы подготовленной к HDR карты окружения
После того, как карта окружения с расширенным динамическим диапазоном готова, в HDR-шейдере необходимо преобразовать цель визуализации в формат с плавающей точкой. Для этого просто дважды щелкните по каждой цели визуализации и смените формат текстуры на A16R16G16B16F.
Следующий шаг — это использование альфа-канала карты окружения для вычисления реального HDR-значения. Это выполняется путем умножения цвета окружения на альфа-канал при визуализации каждого объекта, с учетом того, что альфа-значение находится в диапазоне от нуля до 64. Это приводит к следующему фрагменту кода пиксельного шейдера:
color = color * (1.0+(color.a*64.0));
Эта строка кода шейдера берет альфа-значение в диапазоне от нуля до единицы и преобразует его в целочисленный множитель в диапазоне от единицы до 64. Полученное значение затем используется в качестве множителя для цветового значения, получаемого из карты окружения.
В шейдере пропущена только одна вещь — управление экспозицией. Для этого во-первых нужна переменная для хранения значения экспозиции. Создайте новую переменную с именем Exposure_Level типа SCALAR. Это значение управляет экспозицией, служа в качестве коэффициента масштабирования для визуализации цветов цели при их копировании в экранный буфер.
Для этого нам надо модифицировать ранее разработанный пиксельный шейдер, чтобы масштабировать полученные значения на основании значения экспозиции. Данные изменения приводят к следующему коду:
sampler Texture0; float4 ps_main(float3 dir: TEXCOORD0) : COLOR { // Считываем текстуру и определяем цвет HDR на основании // альфа-канала и уровня экспозиции float4 color = texCUBE(Environment, dir); return color * ((1.0+(color.a*64.0))* Exposure_Level); }
С этим шейдером вы можете увидеть визуализацию HDR-окружения. Попробуйте различные значения экспозиции и посмотрите как изменяется сцена. На рис. 8.3 показаны результаты визуализации для различных значений экспозиции.
Полная версия данного шейдера находится на прилагаемом CD-ROM в файле shader_1.rfx.
Рис. 8.3. Различные значения экспозиции и эффект, оказываемый ими на визуализируемую сцену
Человеческий глаз автоматически изменяет диафрагму, приспосабливаясь к окружающему освещению. Возможно, вы захотите воспроизвести это поведение в своих визуализациях.
Автоматический контроль экспозиции старается регулировать среднюю яркость сцены. Идея в том, что средняя яркость сцены должна быть равна примерно 0.5, поскольку отображаемый диапазон интенсивности простирается от нуля до единицы. Если известна средняя яркость, значение экспозиции может быть вычислено по формуле:
Экспозиция = 0.5 / Средняя_яркость;
Помните, что экспозиция должна медленно адаптироваться к сцене, а не меняться мгновенно. Для этого можно использовать следующий код:
Экспозиция = lerp(Экспозиция, 0.5 / Средняя_яркость, Скорость_изменения_экспозиции);
Вам необходимо определить среднюю яркость сцены, а это непростая задача. Во-первых, вы можете сделать это в DirectX или OpenGL-приложении, заблокировав текстуру и программно вычислив среднее значение, перебрав все пиксели. Однако, на большинстве компьютеров это приведет к значительному снижению скорости работы.
Другой способ аппроксимации того же результата состоит в использовании цели визуализации для вычисления среднего значения с использованием преимуществ аппаратуры визуализации. Если у вас есть последовательный набор текстур визуализации, каждая из которых в два раза меньше своей предшественницы, вы можете использовать простой фильтр свертки для копирования начальной сцены из одной цели визуализации в другую. Когда размер цели визуализации станет равным одному пикселю, этот единственный пиксель будет представлять среднее значение для исходной сцены. Затем можно использовать эту однопиксельную текстуру в качестве входного параметра для шейдера с автоматическим контролем экспозиции.
netlib.narod.ru | < Назад | Оглавление | Далее > |