ldr что это в камере
sit: LDR и HDR.
Други мои, решил немного про hdr написать, что это и для чего. и пока писал начал путаться.
Почитайте, поправьте меня плиз ))
Наши глаза непрерывно приспосабливаются к изменению освещения, постоянно регулируя
чувствительность к свету. Способность человеческого зрения настраивается на различную силу света,
позволяет видеть относительно чётко при разных условиях освещения и в большом динамическом
диапазоне яркости света, особенно при значительном смещении этого динамического диапазона,
например, при наблюдении заката.
High Dynamic Range (HDR) в 3D графике – это рендеринг в широком световом динамическом
диапазоне, суть которого заключается в описании интенсивности и цвета реальными физическими
величинами. Привычной моделью описания изображения является RGB, когда все цвета
представлены в виде суммы основных цветов: красного, зеленого и синего, с разной интенсивностью
в виде значений от 0 до 255 для каждого.
Отношение максимальной интенсивности к минимальной называется динамическим диапазоном.
Так, динамический диапазон модели RGB составляет 256:1 или 100:1 cd/m 2 (два порядка).
Эта модель описания цвета и интенсивности общепринято называется Low Dynamic Range (LDR).
Суть рендеринга HDR изображений в использовании значений интенсивности и цвета в реальных
физических величинах или линейно пропорциональных и в том, чтобы использовать не целые числа,
а числа с плавающей точкой с большой точностью (например, 16 или 32 бита). Это снимет
ограничения модели RGB, а динамический диапазон изображения серьезно увеличится.
Но затем любое HDR изображение можно вывести на любом средстве отображения (том же RGB мониторе),
с максимально возможным качеством для него при помощи цветокоррекции.
Рендеринг HDR позволяет изменять экспозицию уже после того, как мы отрендерили изображение.
Это дает нам возможность имитировать эффект адаптации человеческого зрения (перемещение
из ярких открытых пространств в темные помещения и наоборот), позволяет выполнять физически
правильное освещение, а также является унифицированным решением для применения эффектов
постобработки (glare, flares, bloom, motion blur). Алгоритмы обработки изображения, цветокоррекцию
, гамма-коррекцию и другие методы постобработки качественней выполнять в HDR.
Наша цель не в том, чтобы отобразить изображение HDR, а в том, чтобы воссоздать реалистичное
изображение LDR из исходных данных HDR, изменяя яркость света для реалистичного освещения
нашего проекта. Такая возможность имеется при визуализации 32-разрядных изображений (форматы файлов *.hdr, *.exr, *.tif).
Изображения HDR сохраняются в 8-разрядных файлах, где альфа-канал служит для хранения порядка
числового значения цвета каждого пикселя при его экспоненциальном представлении. Это значение больше,
чем допускается сохранить в 32-разрядном изображении. В итоге диапазон таких значений оказывается
практически бесконечным и может представлять уровни яркости, которые не ограничиваются линейным
изменением от чёрного к белому цветам.
Режимы HDR, LDR.
Режимы HDR, LDR.
Стандартной моделью описания цвета является модель RGB, когда любой цвет получается при смешении трех базовых цветов (красного, зеленого и синего), а интенсивность каждого компонентного цвета задается в виде градаций от 0 до 255. При этом для описания каждого компонентного цвета используется 8 бит, что позволяет описать 256 цветовых оттенков, а всего можно описать 16777216 цветов (224).
Отношение максимальной интенсивности к минимальной называется динамическим диапазоном. Так, динамический диапазон модели RGB составляет 256:1. Эту модель описания цвета и интенсивности принято называть Low Dynamic Range (LDR).
Понятно, что модель RGB с ее низким динамическим диапазоном плохо соответствует реальным возможностям человеческого зрения.
Режим HDR— это режим рендеринга в широком динамическом диапазоне (High Dynamic Range). Идея режима HDR заключается в том, чтобы для описания цветовых компонентов и интенсивности использовать числа с плавающей точкой с большой точностью (например, 16 или 32 бита). Это снимет ограничения модели RGB, а динамический диапазон изображения серьезно увеличится.
У режима HDR есть множество и других возможностей, которые можно задействовать для повышения реалистичности изображения. К примеру, режим HDR дает возможность имитировать эффект адаптации человеческого зрения к меняющимся условиям освещения. Кроме того, данный режим является эффективным для применения постобработки и позволяет более качественно реализовывать такие эффекты, как цветокоррекция, гамма-коррекция, glare (эффект блеска), flares (эффект вспышки), bloom (освещение мягким светом) и motion blur (эффект движения).
Графические процессоры серии GeForce 8800 уже поддерживали процесс рендеринга HDR (High Dynamic Range) с 128-битной точностью не только в режиме FP16 (64-битный цвет), но и FP32 (128-битный цвет), которые могут обрабатываться одновременно с процессом антиалиасинга. Это позволяет добиться реалистичных эффектов освещения и наложения теней, при этом обеспечиваются высокая динамика и детализация самых затемненных и самых светлых объектов. Правда, нужно отметить, что не все существующие сегодня мониторы способны выводить изображение в широком динамическом диапазоне. Поэтому даже в случае использования режима HDR при ренедеринге для вывода изображения на экран такого монитора все равно будет использоваться стандартная модель RGB. В связи с этим сегодня режим HDR можно рассматривать только как эффективное средство для создания различных визуальных эффектов.
«Что я вижу» vs «Что видит моя камера»: как DNN улучшает детали в переэкспонированных и недоэкспонированных изображениях
May 7, 2018 · 4 min read
Ни одна современная камера не сравнится с глазами человека. Если человек смотрит на восход и закат, когда виден огромный разрыв между светлыми и темными тонами, он в состоянии разглядеть мельчайшие детали. Камерам же сложно в этих ситуациях. В результате получается фотографии с угольно чёрными тенями и слепяще белыми светлыми участками.
Исследователи из университета Гонконга и Даляньского технологического университета предложили новый метод преобразования изображений в визуально привлекательное, с помощью глубоких нейронных сетей.
Предлагаемый метод исправляет изображение со слишком или недостаточно долгой экспозицией и привносит много деталей. Метод работает со стандартным LDR изображением (изображение LDR — это изображение с низким динамическим диапазоном), и создает улучшенное изображение, всё ещё в диапазоне LDR, но визуально обогащенное восстановленными деталями. Глубокая нейронная сеть возвращает детали, которые лежат в диапазоне HDR (высокий динамический диапазон), но уменьшились в диапазоне LDR. Здесь и кроется вся магия.
Новый метод называется Deep Reciprocating HDR Transformation, он работает путем применения взаимного преобразования, использующего две глубокие нейронные сети. Идея работы проста: взяв образ LDR, детали реконструируются в области HDR и изображение переводится обратно в область LDR, обогащенную деталями. Хотя это звучит просто, есть два трюка, о которых расскажем ниже.
Чтобы сделать взаимное преобразование, используются две сверточные нейронные сети (CNN). Первая называется сетью HDR оценки, она принимает входное изображение, кодирует в скрытое представление более низкого диапазона, а затем декодирует это представление для восстановления HDR изображения. Вторая, называемая сетью LDR коррекции, выполняет обратное преобразование: принимает оцененное HDR изображение из первой сети и выводит исправленное LDR изображение. Обе сети — простые автокодировщики, кодирующие данные в скрытое представление размера 512.
Эти две сети обучаются совместно и имеют одинаковую архитектуру. Однако, как уже упоминалось выше, есть два трюка: оптимизация и функция затрат, которые дают решение проблемы.
Сеть оценки HDR
Первая сеть обучается прогнозированию данных HDR, она обучена с использованием ELU активизации и нормализации пакетов, а функция потерь — простая средняя квадратичная ошибка. И здесь зарыт первый трюк: функция потери MSE определяется с использованием разности между выходной и основной истиной, с измененными константами, используемыми для преобразования данных HDR в LDR.
Коррекция LDR
Две сети автокодировщика имеют одинаковую архитектуру и используют пропускные соединения. Полная архитектура сети:
Каждая сеть состоит из пяти convolutional (сверточных) и пяти deconvolution (развертывающихся) слоев:
Conv 1 Layer: 9 x 9 размер ядра, 64 карты признаков
Conv 2 Layer: 5 x 5 размер ядра, 64 карты признаков
Conv 3 Layer: 3 x 3 размер ядра, 128 карт признаков
Conv 4 Layer: 3 x 3 размер ядра, 256 карт признаков
Conv 5 Layer: 3 x 3 размер ядра, 256 карт признаков
Скрытое представление: 1 x 512
Deconv 1 Layer: 3 x 3 размер ядра, 256 карт признаков
Deconv 2 Layer: 3 x 3 размер ядра, 256 карт признаков
Deconv 3 Layer: 3 x 3 размер ядра, 128 карт признаков
Deconv 4 Layer: 5 x 5 размер ядра, 64 карты признаков
Deconv 5 Layer: 9 x 9 размер ядра, 64 карты признаков
Обучение проводилось с использованием алгоритма оптимизатора ADAM с начальной скоростью обучения 1e-2.
Набор данных
Два набора данных используются для обучения и тестирования метода: набор данных городской панорамы и уличной панорамы Sun360. Также, авторы отмечают, что использовали Photoshop при создании правдивых LDR изображений с человеческим контролем для промежуточной задачи. Размер тренировочного набора, который используется для тренировки обеих сетей, составляет 40 000 изображений (исходное изображение LDR, истинное HDR и истинное LDR изображение).
Результаты
Как утверждают авторы, предложенный метод работает лучше современных аналогов. Оценка проводилась путем сравнения с Cape, WVM, SMF, L0S и DJF.
Оценка сложная, так как главной целью является создание визуально приятных изображений, которые трудно поддаются количественной оценке, а также субъективны. Однако авторы используют ряд различных оценочных показателей. Авторы использовали HDR-VDP-2 характеристику для оценки первой сети, которая отражает восприятие человека, а для оценки метода и сравнения с существующими методами использовались показатели: PSNR, SSIM, FSIM.
HDR vs LDR, реализация HDR Rendering
Как я и обещал – публикую вторую статью о некоторых моментах разработки игр в трех измерениях. Сегодня расскажу об одной технике, которая используется почти любом проекте ААА-класса. Имя ей — HDR Rendering. Если интересно — добро пожаловать под хабракат.
Взять, например, Crysis 2:
В этих двух скриншотах нет никакого DirextX10 и DirectX11. Так отчего люди думают, что делать что-то на XNA — заниматься некрофилией? Да, Microsoft перестала поддерживать XNA, но запаса того, что там есть — хватит на 3 года точно. Более того, сейчас существует monogame, он опенсорсный, кроссплатформенный (win, unix, mac, android, ios, etc) и сохраняет всю ту же архитектуру XNA. Кстати, FeZ из прошлой статьи написан с использованием monogame. Ну и напоследок — статьи направленные в целом то на компьютерную графику в трех измерениях (все эти положения справедливы и для OpenGL, и для DirectX), а не XNA — как можно подумать. XNA в нашем случае всего-лишь инструмент.
Ладно, поехали
Обычно в играх используется LDR (Low Dynamic Range) рендеринг. Это означает, что цвет бэк-буфера ограничен в пределах 0…1. Где на каждый канал уделяется по 8 бит, а это 256 градаций. К примеру: 255, 255, 255 — белый цвет, все три канала (RGB) равны максимальной градации. Понятие LDR несправедливо применять к понятию реалистичного рендеринга, т.к. в реальном мире цвет задается далеко не нулем и единицей. На помощь к нам приходит такая технология, как HDRR. Для начала, что такое HDR? High Dynamic Range Rendering, иногда просто «High Dynamic Range» — графический эффект, применяемый в компьютерных играх для более выразительного рендеринга изображения при контрастном освещении сцены. В чем заключается суть этого подхода? В том, что мы рисуем нашу геометрию (и освещение) не ограничиваясь нулем и единицей: один источник света может дать яркость пикселя в 0.5 единиц, а другой в 100 единиц. Но как можно заметить на первый взгляд, наш экран воспроизводит как раз тот самый LDR формат. И если мы все значения цвета бэк-буфера разделим на максимальную яркость в сцене — получится тот же LDR, а источник света в 0.5 единиц почти не будет виден на фоне второго. И как раз для этого был придуман особый метод называемый Tone Mapping. Суть этого подхода, что мы приводим динамический диапазон к LDR в зависимости от средней яркости сцены. И для того, чтобы понять о чем я, рассмотрим сцену: две комнаты, одна комната indoor, другая outdoor. Первая комната — имеет искусственный источник света, вторая комната — имеет источник света в виде солнца. Яркость солнца на порядок выше, чем яркость искусственного источника света. И в реальном мире, при нахождении в первой комнате — мы адаптируемся к этому освещению, при входе в другую комнату мы адаптируемся к другому уровню освещения. При взгляде из первой комнаты во вторую — она будет казаться нам чрезмерно яркой, а при взгляде из второй в первую — черной.
Еще один пример: одна outdoor комната. В этой комнате — есть само солнце и рассеянный свет от солнца. Яркость солнца на порядок выше, чем его рассеянный свет. В случае LDR значения яркости света были бы равны. Поэтому, используя HDR можно добиться реалистичных бликов с различных поверхностей. Это очень заметно на воде:
Или на бликах с сурфейса:
Ну и контрастность сцены в целом (слева HDR, справа LDR):
Вместе с HDR принято применять и технологию Bloom, яркие области размываются и накладываются поверх основного изображения:
Это делает освещение еще мягче.
Так же, в виде бонуса — расскажу про Color Grading. Этот поход повсеместно применяется в играх ААА-класса.
Color Grading
Очень часто в играх сцена должна иметь свой цветовой тон, этот цветовой тон может быть общим как для всей игры, так и для отдельных участков сцены. И чтобы каждый раз не иметь по сто шейдеров-постпроцессоров — используют подход Color Grading. В чем суть этого подхода?
Знаменитые буквы RGB — цветовое трехмерное пространство, где каждый канал это своеобразная координата. В случае формата R8G8B8: 255 градаций на каждый канал. Так вот, что будет, если мы применим обычные операции обработки (например, кривые или контрастность) к этому пространству? Наше пространство изменится и в будущем мы можем назначить любому пикселю — пиксель из этого пространства.
Создадим простое RGB пространство (хочу заменить, что берем мы каждый 8-ой пиксель, т.к. если будем брать все 256 градаций, то размер текстуры будет очень большим):
Это трехмерная текстура, где на каждую ось — свой канал.
И возьмем какую-нибудь сцену, которую нужно модифицировать (добавив при этом на изображение наше пространство):
Проводим нужные нам трансформации (на глаз):
И извлекаем наше модифицируемое пространство:
Теперь, по этому пространству — мы можем применить все модификации с цветом к любому изображению. Просто сопоставляя оригинальный цвет с измененным пространством цвета.
Реализация
Ну и кратко по реализации HDR в XNA. В XNA формат бэк-буфера задается (в основном) R8G8B8A8, т.к. рендеринг прямо на экран не может поддерживать HDR априори. Для этого обхода — нам нужно создать новый RenderTarget (ранее я описывал работу онных тут) с особым форматом: HalfVector4*. Этот формат поддерживает плавающие значения у RenderTarget.
* — в XNA есть такой формат — как HDRBlendable, это все тот же HalfVector4 — но сам RT занимает меньше места (т.к. на альфа канал нам не нужен floating-point).
Заведем нужный RenderTarget:
Создаем новый RT с размерами бэк-буфера (разрешением экрана) с отключенным mipmap (т.к. эта текстура будет рисоваться на экранном кваде) с форматом сурфейса — HdrBlendable (или HalfVector4) и 24-ех битным буфером глубины / стенсил-буферов 8 бит. Так же отключим multisampling.
У этого RenderTarget важно включить буфер глубины (в отличии от обычного post-process RT), т.к. мы будем рисовать туда нашу геометрию.
Далее — все как в LDR, мы рисуем сцену, только теперь не нужно ограничиваться рисованием яркости [0. 1].
Добавим skybox с номинальной яркостью умноженной на три и классический чайник Юта с DirectionalLight-освещением и Reflective-поверхностью.
Сцена создана и теперь нам нужно как-нибудь формат HDR привести к LDR. Возьмем самый простой ToneMapping — разделим все эти величины на условное значение max.
Покрутим камерой и поймем, что сцена все равно обладает статичностью и подобную картинку можно с легкостью добиться, применив контрастность к изображению.
В реальной же жизни — наш глаз адаптируется к нужному освещению: в плохо освещенной комнате мы все равно видим, но до тех пор, пока перед нашими глазами нет яркого источника света. Это называется световой адаптацией. И самое крутое то, что HDR и цветовая адаптация идеально сочетается друг с другом.
Теперь нам нужно вычислить среднее значение цвета на экране. Это довольно проблематично, т.к. формат с плавающим значением не поддерживает фильтрацию. Поступим следующим образом: создадим N-ое кол-во RT, где каждый следующий меньше предыдущего:
И будем рисовать каждый предыдущий RT в следующий RT применяя некоторое размытие. После этих циклов у нас получится текстура 1×1, которая собственно и будет содержать средний цвет.
Если это все сейчас запустить, то цветовая адаптация действительно будет, но она будет моментальной, а так не бывает. Нам нужно, чтобы при взгляде с резко темной области на резко светлую — сначала чувствовали слепоту (в виде повышенной яркости), а затем все приходило в норму. Для этого достаточно завести еще один RT 1×1, который и будет отвечать за текущее значение адаптации, при этом, каждый кадр мы приближаем текущую адаптацию к рассчитанному в данный момент цвету. Причем, значение этого приближения должно быть завязано на все том же gameTime.ElapsedGameTime, чтобы кол-во FPS не влияло на скорость адаптации.
Ну и теперь в качестве параметра max для _toneSimple можно передавать наш средний цвет.
Существует масса формул ToneMapping‘a, вот некоторые из них:
Я же использую собственную формулу:
Ну и следующий этап это Bloom (частично я его описывал тут) и Color Grading:
Использование Color Grading:
Любое цветовое значение пикселя (RGB) после ToneMapping‘a лежит в пределах от 0 до 1. Наше цветовое пространство Color Grading тоже условно лежит в пределах от 0 до 1. Поэтому, мы можем заменить текущее значение цвета пикселя на цвет пикселя в цветовом пространстве. При этом, фильтрация сэмплера произведет линейное интерполирование между нашими 32 значениями на карте Color Grading. Т.е. мы «как-бы»
подменяем эталонное цветовое пространство — нашим измененным.
Для Color Grading нужно ввести следующую функцию:
где ColorGradingSampler — трехмерный сэмплер.
Ну и LDR/HDR сравнение:
LDR:
HDR:
Заключение
Этот простой подход — одна из фишек 3D AAA-игр. И как видите — реализован он может быть и на старом-добром DirectX9c, причем реализация в DirectX10+ принципиально ничем отличатся. Больше информации вы найдете в исходниках.
Так же стоит отличать друг от друга HDRI (используется в фотографии) и HDRR (используется в рендеринге).
Заключение 2
Learn OpenGL. Урок 5.7 — HDR
При записи во фреймбуфер значения яркости цветов приводятся к интервалу от 0.0 до 1.0. Из-за этой, на первый вгляд безобидной, особенности нам всегда приходится выбирать такие значения для освещения и цветов, чтобы они вписывались в это ограничение. Такой подход работает и даёт достойные результаты, но что случится, если мы встретим особенно яркую область с большим количеством ярких источников света, и суммарная яркость превысит 1.0? В результате все значения, большие чем 1.0, будут приведены к 1.0, что выглядит не очень красиво:
Так как для большого количества фрагментов цветовые значения приведены к 1.0, получаются большие области изображения, залитые одним и тем же белым цветом, теряется значительное количество деталей изображения, и само изображение начинает выглядеть неестественно.
Решением данной проблемы может быть снижение яркости источников света, чтобы на сцене не было фрагментов ярче 1.0: это не лучшее решение, вынуждающее использовать нереалистичные значения освещения. Лучший подход заключается в том, чтобы разрешить значениям яркости временно превышать яркость 1.0 и на финальном шаге изменить цвета так, чтобы яркость вернулась к диапазону от 0.0 до 1.0, но без потери деталей изображения.
Дисплей компьютера способен показывать цвета с яркостью в диапазоне от 0.0 до 1.0, но у нас нет такого ограничения при расчёте освещения. Разрешая цветам фрагмента быть ярче единицы, мы получаем намного более высокий диапазон яркости для работы — HDR (high dynamic range). С использованием hdr яркие вещи выглядят яркими, тёмные вещи могут быть реально тёмными, и при этом мы будем видеть детали.
Часть 2. Базовое освещение
Часть 3. Загрузка 3D-моделей
Часть 4. Продвинутые возможности OpenGL
Часть 5. Продвинутое освещение
Изначально высокий динамический диапазон использовался в фотографии: фотограф делал несколько одинаковых фотографий сцены с различной экспозицией, захватывая цвета почти любой яркости. Комбинация этих фотографий формирует hdr изображение, в котором становится различимым большинство деталей за счёт сведения изображений с разными уронями экспозиции. Например, ниже на левом изображении хорошо видны сильно освещённые фрагменты изображения (посмотрите на окно), но эти детали пропадают при использовании высокой экспозиции. Однако, высокая экспозиция делает различимымидетали на тёмных областях изображения, которые до этого не были видны.
Это похоже на то, как работает человеческий глаз. При недостатке света глаз приспосабливается, так что тёмные детали становятся хорошо различимыми, и аналогично для ярких областей. Можно сказать, что человеческий глаз имеет автоматическу настройку экспозиции, зависящую от яркости сцены.
HDR рендеринг работает примерно так же. Мы разрешаем при рендере использовать большой диапазон значений яркости, чтобы собрать информацию и о ярких, и о тёмных деталях сцены, и в конце мы преобразуем значения из диапазона HDR обратно в LDR (low dynamic range, диапазон от 0 до 1). Это преобразование называется тональной компрессией (tone mapping), существует большое количество алгоритмов, нацеленных на сохранение большинства деталей изображения при конвертации в LDR. Эти алгоритмы часто имеют параметр экспозиции, который позволяет лучше показывать яркие или тёмные области изображения.
Использование HDR при рендеринге позволят нам не только превышать LDR диапазон от 0 до 1 и сохранять больше деталей изображения, но также даёт возможность указывать реальную яркость источников света. Например, солнце имеет намного большую яркость света, чем что-нибудь типа фонарика, так почему бы не настроить солнце таким (например, присвоить ему яркость 10.0)? Это позволит нам лучше настроить освещение сцены с более реалистичными параметрами яркости, что было бы невозможно при LDR рендеринге и диапазоне яркости от 0 до 1.
Так как дисплей показывают яркость только от 0 до 1, мы вынуждены конвертировать используемый HDR диапазон значений обратно к диапазону монитора. Просто отмасштабировать диапазон не будет хорошим решением, так как на изображении начнут преобладать яркие области. Однако мы можем использовать различные уравнения или кривые для преобразования значений HDR в LDR, что даст нам полный контроль над яркостью сцены. Этот преобразование называется тональной компрессией (tone mapping) и являетя финальным шагом HDR рендеринга.
Фреймбуферы с плавающей точкой
Для реализации HDR рендеринга нам нужен способ, чтобы предотвратить приведение значений к диапазону от 0 до 1 результатов работы фрагментного шейдера. Если фреймбуфер использует нормализованный формат с фиксированной точкой (GL_RGB) для буферов цвета, то OpenGL автоматически ограничнивает значения перед сохранением во фреймбуфер. Это ограничние применяется для большинства форматов фреймбуфера, кроме форматов с плавающей точкой.
Создание floating point буфера отличается от обычного буфера только тем, что в нём используется другой внутренний формат:
Если к фреймбуферу присоединён floating point буфер для цвета, мы можем рендерить сцену в него с учётом того, что значения цвета не будут ограничены диапазоном от 0 до 1. В коде к данной статье мы сначала рендерим сцену в floating point фреймбуфер и после этого выводим содержимое буфера цвета на полкоэкранный прямоугольник. Это выглядит примерно так:
Здесь значения цвета, содержащиеся в буфере цвета, могут быть больше 1. Для этой статьи была создана сцена с большим вытянутым кубом, выглядящим как туннель с четырьмя точечными источниками света, один из них расположен в конце туннеля и обладает огромной яркостью.
Рендеринг в floating point буфер точно такой же, как если бы мы рендерили сцену в обычный фреймбуфер. Новым является только фрагментный hdr шейдер, который занимается простой закраской полноэкранного прямоугольника значениями из текстуры, являющейся буфером цвета с плавающей точкой. Для начала напишем простой шейдер, передающий входные данные без изменений:
Мы берём входные данные из floating point буфера цвета и используем их в качестве выходных значений шейдера. Однако, так как 2д прямоугольник рендерится в фреймбуфер по-умолчанию, выходные значения шейдера будут ограничены интервалом от 0 до 1, не смотря на то, что в некоторых местах значения больше 1.
Становится очевидным, что слишком большие значения цвета в конце туннеля ограничены единицей, так как значительная часть изображения полностью белая, и мы теряем детали изображения, которые ярче единицы. Так как мы используем HDR значения напрямую в качестве LDR, это эквивалентно отсутствию HDR. Чтобы исправить это, мы должны отобразить различные значения цветов обратно в диапазон от 0 до 1 без потери каких-либо деталей изображения. Для этого применим тональную компрессию.
Тональная компрессия
Тональная компрессия — преобразование значений цвета, чтобы уместить их в диапазоне от 0 до 1 без потери деталей изображения, часто в сочетании с приданием изображению желаемого баланса белого.
Самый простой алгоритм тональной компрессии известен как алгоритм Рейнхарда (Reinhard tone mapping). Он отображает любые HDR значения в LDR диапазаон. Добавим этот алгоритм в предыдущий фрагментный шейдер, а так же применим гамма-коррекцию (и использование SRGB текстур).
Прим. пер. — при малых значениях х функция x/(1+x) ведёт себя примерно как х, при больших х — стремится к единице. График функции:
С тональной компрессией Рейнхарда мы больше не теряем деталей в ярких областях изображения. Алгоритм отдаёт предпочтение ярким областям, делая тёмные области менее отчётливыми.
Здесь вы снова можете видеть такие детали в конце изображения, как текстура дерева. С этим относительно простым алгоритмом мы хорошо видим любые цвета из HDR диапазона и можем контролировать освещение сцены без потери деталей изображения.
Стоит отметить, что мы можем использовать тональную компрессию напрямую в конце нашего шейдера для рассчёта освещения, и тогда нам вообще не понадобится floating point фреймбуфер. Однако, на более сложных сценах вы часто будете встречаться с необходимостью хранить промежуточные HDR значения в floating point буферах, так что это вам пригодится.
Ещё одной интересной возможностью тоновой компрессии является использование параметра экспозиции. Возможно, вы помните, что на изображениях в начале статьи различные детали были видны при разных значениях экспозиции. Если мы имеем сцену, на которой сменяются день и ночь, имеет смысл использовать низкую экспозицию днём и высокую ночью, что схоже с адаптацией человеческого глаза. С таким параметром экспозиции мы сможем настраивать параметры освещения, которые будут работать и днём и ночью при разных условиях освещения.
Относительно простой алгоритм тональной компрессии с экспозицией выглядит так:
Прим. пер: добавлю график и для этой функции c экспозицией 1 и 2:
Здесь мы определили переменную для экспозиции, которая по умолчанию равна 1 и позволяет нам более точно выбрать баланс между качеством отображения тёмных и ярких областей изображения. Например, с большой экспозицией мы видим значительно больше подробностей на тёмных областях изображения. И наоборот, малая экспозиция делает неразличимыми тёмные области, но позволяет лучше увидеть яркие области изображения. Ниже приведены изображения туннеля с различными уровнями экспозиции.
Эти изображения явно показывают преимущества hdr рендеринга. При изменении уровня экспозиции мы видим больше деталей сцены, которые были бы потеряны при обычном рендеринге. Возьмите для примера конец туннеля — с нормальной экспозицией текстура дерева едва видна, но при низкой экспозиции текстуру превосходно видно. Аналогично, при высокой экспозиции очень хорошо видны детали в тёмных областях.
Исходный код для демо здесь
Больше HDR
Те два алгоритма тоновой компрессии, которые были показаны, являются лишь малой частью среди большого количества более продвинутых алгоритмов, каждый из которых имеет свои сильные и слабые стороны. Некоторые алгоритмы лучше подчёркивают определённые цвета/яркости, некоторые алгоритмы показывают одновременно тёмные и яркие области, выдавая более красочные и детализированные изображения. Так же существует множество способов, известных как автоматичесий выбор экспозиции (automatic exposure adjustment) или адаптация глаз (eye adaptation). В них определяется яркость сцены на предыдущем кадре и (медленно) изменяется параметр экспозиции, так что тёмная сцена потихоньку становится ярче, а яркая — темнее: схоже с привыканием человеческого глаза.
Реальные преимущества HDR становятся лучше всего видны на больших и сложных сценах с серьёзными алгоритмами освещения. В целях обучения в данной статье использовалась максимально простая сцена, так как создание большой сцены может быть сложным. Несмотря на простоту сцены, на ней видны некоторые преимущества hdr рендеринга: в тёмных и светлых областях изображения не теряются детали, так как они сохраняются при помощи тоновой компрессии, добавление множественных источников света не приводит к появлению белых областей, и значения не обязаны умещаться в LDR диапазон.
Более того, HDR рендеринг также делает некоторые интересные эффекты более правдоподобными и реалистичными. Одним из таких эффектов является блум (bloom), который мы обсудим в следующей статье.