HDR vs LDR, реализация HDR Rendering

  • Tutorial


Как я и обещал – публикую вторую статью о некоторых моментах разработки игр в трех измерениях. Сегодня расскажу об одной технике, которая используется почти любом проекте ААА-класса. Имя ей — HDR Rendering. Если интересно — добро пожаловать под хабракат.


Но сначала нужно поговорить. Исходя из прошлой статьи — понял, что и аудитория хабрахабра похоронила технологию Microsoft XNA. Делать, якобы, с помощью его что-то — все равно, что писать игры на ZX Spectrum. В пример мне привели: “Есть же ведь SharpDX, SlimDX, OpenTK!”, даже приводили в пример Unity. Но остановимся на первых трех, все это — чистой воды врапперы DX’a под .NET, а Unity так вообще движок-песочница. Что вообще из себя представляет DirectX10+? Ведь его нет и не будет в XNA. Так вот, подавляющие кол-во эффектов, фишек и технологий реализуется именно на базе DirectX9c. А DirectX10+ вводит лишь дополнительный функционал (SM4.0, SM5.0).

Взять, например, 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:
private void _makeRenderTarget() 
{
            // Use regular fp16 
            _sceneTarget = new RenderTarget2D(GraphicsDevice, 
                GraphicsDevice.PresentationParameters.BackBufferWidth, 
                GraphicsDevice.PresentationParameters.BackBufferHeight, 
                false,
                SurfaceFormat.HdrBlendable, DepthFormat.Depth24Stencil8,
                0, 
                RenderTargetUsage.DiscardContents); 
} 


Создаем новый RT с размерами бэк-буфера (разрешением экрана) с отключенным mipmap (т.к. эта текстура будет рисоваться на экранном кваде) с форматом сурфейса — HdrBlendable (или HalfVector4) и 24-ех битным буфером глубины / стенсил-буферов 8 бит. Так же отключим multisampling.
У этого RenderTarget важно включить буфер глубины (в отличии от обычного post-process RT), т.к. мы будем рисовать туда нашу геометрию.

Далее — все как в LDR, мы рисуем сцену, только теперь не нужно ограничиваться рисованием яркости [0...1].
Добавим skybox с номинальной яркостью умноженной на три и классический чайник Юта с DirectionalLight-освещением и Reflective-поверхностью.

Сцена создана и теперь нам нужно как-нибудь формат HDR привести к LDR. Возьмем самый простой ToneMapping — разделим все эти величины на условное значение max.

float3 _toneSimple(float3 vColor, float max)
{
	return vColor / max;
}


Покрутим камерой и поймем, что сцена все равно обладает статичностью и подобную картинку можно с легкостью добиться, применив контрастность к изображению.

В реальной же жизни — наш глаз адаптируется к нужному освещению: в плохо освещенной комнате мы все равно видим, но до тех пор, пока перед нашими глазами нет яркого источника света. Это называется световой адаптацией. И самое крутое то, что HDR и цветовая адаптация идеально сочетается друг с другом.

Теперь нам нужно вычислить среднее значение цвета на экране. Это довольно проблематично, т.к. формат с плавающим значением не поддерживает фильтрацию. Поступим следующим образом: создадим N-ое кол-во RT, где каждый следующий меньше предыдущего:

int cycles = DOWNSAMPLER_ADAPATION_CYCLES;
            float delmiter = 1f / ((float)cycles+1);
 
            _downscaleAverageColor = new RenderTarget2D[cycles];
            for (int i = 0; i < cycles; i++)
            {
                _downscaleAverageColor[(cycles-1)-i] = new RenderTarget2D(_graphics, (int)((float)width * delmiter * (i + 1)), (int)((float)height * delmiter * (i + 1)), false, SurfaceFormat.HdrBlendable, DepthFormat.None);
            }


И будем рисовать каждый предыдущий RT в следующий RT применяя некоторое размытие. После этих циклов у нас получится текстура 1x1, которая собственно и будет содержать средний цвет.

Если это все сейчас запустить, то цветовая адаптация действительно будет, но она будет моментальной, а так не бывает. Нам нужно, чтобы при взгляде с резко темной области на резко светлую — сначала чувствовали слепоту (в виде повышенной яркости), а затем все приходило в норму. Для этого достаточно завести еще один RT 1x1, который и будет отвечать за текущее значение адаптации, при этом, каждый кадр мы приближаем текущую адаптацию к рассчитанному в данный момент цвету. Причем, значение этого приближения должно быть завязано на все том же gameTime.ElapsedGameTime, чтобы кол-во FPS не влияло на скорость адаптации.

Ну и теперь в качестве параметра max для _toneSimple можно передавать наш средний цвет.

Существует масса формул ToneMapping'a, вот некоторые из них:

Reinhard
float3 _toneReinhard(float3 vColor, float average, float exposure, float whitePoint)
{
  // RGB -> XYZ conversion
  const float3x3 RGB2XYZ = {0.5141364, 0.3238786,  0.16036376,
                             0.265068,  0.67023428, 0.06409157,
                             0.0241188, 0.1228178,  0.84442666};				                    
  float3 XYZ = mul(RGB2XYZ, vColor.rgb);
  
  // XYZ -> Yxy conversion
  float3 Yxy;
  Yxy.r = XYZ.g;                            // copy luminance Y
  Yxy.g = XYZ.r / (XYZ.r + XYZ.g + XYZ.b ); // x = X / (X + Y + Z)
  Yxy.b = XYZ.g / (XYZ.r + XYZ.g + XYZ.b ); // y = Y / (X + Y + Z)
    
  // (Lp) Map average luminance to the middlegrey zone by scaling pixel luminance
  float Lp = Yxy.r * exposure / average;         
                
  // (Ld) Scale all luminance within a displayable range of 0 to 1
  Yxy.r = (Lp * (1.0f + Lp/(whitePoint * whitePoint)))/(1.0f + Lp);
  
  // Yxy -> XYZ conversion
  XYZ.r = Yxy.r * Yxy.g / Yxy. b;               // X = Y * x / y
  XYZ.g = Yxy.r;                                // copy luminance Y
  XYZ.b = Yxy.r * (1 - Yxy.g - Yxy.b) / Yxy.b;  // Z = Y * (1-x-y) / y
    
  // XYZ -> RGB conversion
  const float3x3 XYZ2RGB  = { 2.5651,-1.1665,-0.3986,
                              -1.0217, 1.9777, 0.0439, 
                               0.0753, -0.2543, 1.1892};

  return mul(XYZ2RGB, XYZ);
}


Exposure
float3 _toneExposure(float3 vColor, float average)
{
	float T = pow(average, -1);

	float3 result = float3(0, 0, 0);
	result.r = 1 - exp(-T * vColor.r);
	result.g = 1 - exp(-T * vColor.g);
	result.b = 1 - exp(-T * vColor.b);

	return result;
}



Я же использую собственную формулу:

Exposure2
float3 _toneDefault(float3 vColor, float average)
{
	float fLumAvg = exp(average);	

	// Calculate the luminance of the current pixel
	float fLumPixel = dot(vColor, LUM_CONVERT);	
	
	// Apply the modified operator (Eq. 4)
	float fLumScaled = (fLumPixel * g_fMiddleGrey) / fLumAvg;	
	float fLumCompressed = (fLumScaled * (1 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1 + fLumScaled);
	return fLumCompressed * vColor;
}



Ну и следующий этап это Bloom (частично я его описывал тут) и Color Grading:

Использование Color Grading:
Любое цветовое значение пикселя (RGB) после ToneMapping'a лежит в пределах от 0 до 1. Наше цветовое пространство Color Grading тоже условно лежит в пределах от 0 до 1. Поэтому, мы можем заменить текущее значение цвета пикселя на цвет пикселя в цветовом пространстве. При этом, фильтрация сэмплера произведет линейное интерполирование между нашими 32 значениями на карте Color Grading. Т.е. мы «как-бы»
подменяем эталонное цветовое пространство — нашим измененным.

Для Color Grading нужно ввести следующую функцию:

float3 gradColor(float3 color)
{
	return tex3D(ColorGradingSampler, float3(color.r, color.b, color.g)).rgb;
}


где ColorGradingSampler — трехмерный сэмплер.

Ну и LDR/HDR сравнение:
LDR:


HDR:


Заключение


Этот простой подход — одна из фишек 3D AAA-игр. И как видите — реализован он может быть и на старом-добром DirectX9c, причем реализация в DirectX10+ принципиально ничем отличатся. Больше информации вы найдете в исходниках.

Так же стоит отличать друг от друга HDRI (используется в фотографии) и HDRR (используется в рендеринге).

Заключение 2


К сожалению, когда я писал в 2012 статьи по геймдеву — откликов и оценок было куда больше, сейчас же мои ожидания слегка не оправдались. Я не гонюсь за оценкой топика. Не хочу, чтобы он искусственно имел высокую оценку или низкую. Я хочу, чтобы он был оценен: не обязательно как: «Хорошая статья!», но и с «Статья на мой взгляд неполная, с %item% ситуация осталась непонятной.». Я рад даже негативной, но конструктивной оценке. А как итог — я публикую статью, а она кое-как собирает пару комментариев и оценок. И с учетом того, что хабрахабр это саморегулируемое сообщество напрашивается вывод: статья не интересна -> публиковать подобное смысла не имеет.

P.S. все мы люди и делаем ошибки и поэтому, если найдете ошибку в тексте — напишите мне личным сообщением, а не спешите писать гневный комментарий!
Share post

Similar posts

AdBlock has stolen the banner, but banners are not teeth — they will be back

More
Ads

Comments 63

    +7
    Спасибо!
      –21
      И с учетом того, что хабрахабр это саморегулируемое сообщество напрашивается вывод: статья не интересна -> публиковать подобное смысла не имеет.

      при всем уважении — целевая аудитория вашей статьи больше на dtf.ru и gamedev.ru
      Я, как человек имевший отношение к геймдеву более 5ти лет назад, нахожу статью интересной но имхо ей самое место на dtf.ru

      Кстати, раздел Color Grading ни асили. Честно признаюсь — ничего не понял. Как на старался (((
        +1
        ЗЫ и, да, спасибо за статью )
          +2
          По Color Grading добавил чуть-чуть информации в статью.
            0
            Это получается пост процессинг?
            Мы за один вызов меняем цветовую гамму всей сцены?
              +2
              Да, все верно, один из этапов пост-процессинга.
                0
                ну тогда боле менее понятно «зачем»
                спасибо
        • UFO just landed and posted this here
            +1
            Ваше право — я все равно считаю эти два сайта более профильными по тематики данной статьи.
            Это не означает что данной статье тут не место — автор интересовался почему не комментируют его статьи. Я высказал свою точку зрения.
            Вы высказали свою — это хабр :-)
            • UFO just landed and posted this here
                +1
                Просто Ваш комментарий выглядит в виде «статья не интересна, идите на dtf.ru и gamedev.ru»

                Я такого не писал.И не имел этого в виду.
            +4
            Статья интересная, и на Хабре её самое место, но время публикации не очень удачное.
            Хабр вообще мало кем читается по выходным.
            +12
            Вместе с HDR принято применять и технологию Bloom

            Пожалуйста, не надо.
              +2
              Вы не любите Bloom? Мне кажется потому, что Bloom без HDR выглядит действительно не очень. А вот в связке — самое оно!
                +4
                Потому что он выглядит не очень при любых условиях.
                  +14
                  Если решение не меняется после этого:
                  Without bloom:
                  image

                  With bloom:
                  image

                  То тогда наши вкусы разные, простите :-)
                    +2
                    Тоже не люблю блум. И на приведённой вами картинке ясно видно почему: картинка с блумом начинает выглядеть как изображение, снятое на камеру. Человек так не видит. Не знаю как вам, но мне не нравиться видеть сцену в игре так, будто я смотрю на неё через экранчик видеокамеры. Раздражает ужасно, особенно пересвеченные области. Хотя, конечно же, это всё дело вкуса.
                      +17
                      Тем более, что традиционное применение — прикрыть фиговым листочком убогость текстур и низкое разрешение в консольных играх и их портах. Как видишь дикое мыло и bloom с blur'ом — точно консоль исходная.
                        +2
                        Может мне зрение надо проверить, но я когда еду по мосту через Волгу, то солнце на волнах бликует с размытием как на этом фото. Может и раздражает / напрягает кого-то, но мне так кажется естественнее и атмосфернее что-ли.
                +6
                Нужно больше статьей про геймдев, хороших и разных :-)

                З.Ы. Эту отношу к хорошим, потому что всё элементарно и применимо.
                  +4
                  Я еще в прошлой статье просил в комментариях высказать об интересах :)
                  Любую ААА-игру, любой эффект и я его попробую описать доступно и просто в обозримом будущем.
                    0
                    Интересно было бы про cell shading почитать. С примерами реализации. На примере того же Borderlands и Borderlands 2.
                      +4
                      Обязательно пишите ещё! Мне бы, например, очень интересно было бы почитать про relief mapping: parallax occlusion mapping, cone step mapping, «вот это вот всё».

                      Bump map vs isosurface2.png

                      Меня это прямо завораживает :)
                        +1
                        Правда, я не знаю, насколько это применимо к современным AAA-играм, я не очень вообще в теме :( Сейчас, наверное, всё это тесселяцией и картами смещения делают? Тогда лучше про них :)
                          0
                          Вообще, да:
                          Освещение с учетом неровностей — называется Normal Mapping.
                          Имитация неровностей без изменения геометрии — называется Parallax Mapping (POM — улучшенный Parallax Mapping)
                          И полное изменение геометрии по карте высот — Displacement Mapping
                          А процесс тесселяции — аппаратное увлечение числа полигонов на модели.
                            0
                            Это, кстати, само по себе интересно, как так получается, что эффективнее выходит передать простую модель на GPU и там её геометрию перед отрисовкой «прокачать», чем отдавать сразу сложную модель с нужной геометрией. Или тут не только в эффективности дело?
                              0
                              Разница в том, чтобы передать информацию о модели в 20к треугольников (все образующие точки, грани, и т.д., в том числе и текстурные координаты с нормалями), алгоритмом тесселяции разбить имеющуюся геометрию на заметно большее количество треугольников (2000000), после чего по карте высот подвигать точки, чем передать на вывод просто 2000000 треугольников (со всеми сопутствующими данными). Да, эти числа не внушают, но это один средненький персонаж (в современном поколении игр уже гораздо больше). С увеличением объектов в сцене, количество загружаемых данных о геометрии увеличивается.
                        0
                        Как говорил мой преподаватель по высшей математике, «Анатолий Андреевич ставит оценки хорошие и разные, но больше разные».

                        Так, что лучше статей хороших, а не «разных» ;)
                        +3
                        Спасибо за статью!
                        Я бы с радостью почитал подобный емкий лаконичный разбор других техник, применяемых в современных 3D-играх. Меня как дилетанта интересуют простые понятия и аббревиатуры, представленные в графический настройках любой игры ААА-класса: алгоритмы сглаживания (FXAA, TXAA, SSAA, MSAA, *AA), алгоритмы освещения, частиц, жидкостей, тесселяция и прочие знакомые, но не понятные мне слова.
                        +3
                        Для фотографов пример с чайником выглядит наоборот: hdr устраняет тени и пересветы, здесь же наоборот пересвет в пол-чайника, как на хинленькой матрице мобильного телефона.
                        Неправильный HDR в ваших играх, само понятие HDR извращено, в первую очередь из-за неправильного по фото-мерка tone mapping.
                          0
                          Что значит неправильное? Оно есть «as is». Другое дело, что у каждого Tone-функция может быть разная. В фотографии идет совмещение снимков с разной экспозицией, поэтому и HDR. А в играх наоборот — разделение HDR.
                            0
                            «Неправильно» с точки зрения фото- и видеосъемки. На примерах как раз LRD является тем, что в съемке является HDR (грубо говоря). Насколько это действительно неправильно — не ясно, но фотографов и операторов (а может и кого-то еще) это слегка удивляет =)

                            ИМХО, в статью стоило добавить объяснение разницы оригинального HDR и игрового.
                              +1
                              ИМХО, в статью стоило добавить объяснение разницы оригинального HDR и игрового.

                              «Оригинальный» HDR — называется HDRI. Игровой HDR — HDRR. Да, действительно, добавил.
                                +2
                                Все правильно.

                                High Dynamic Range — всего лишь «большой динамический диапазон», что означает, что на каком-то этапе получения изображения его реальный динамический диапазон оказывается больше, чем у изображения в восьмибитной (линейной или близкой к ней, но не экспоненциальной или какой-либо еще подобной) шкалой яркостей.

                                В фотографии термин High Dynamic Range Image/Imaging относится (вопреки тому, что думают многие) к изображению (или процессу его получения), которое восстанавливается из отдельных кадров с разной экспозицией или из RAW-изображения (в этом случае «DR» не такой уж и «H»). А дальше происходит Tone Mapping. И вот уже результат (картинку с гнусными серными пятнами и задранной насыщенностью) большинство безграмотно называют HDR/HDRI, хотя она сама по себе является изображением с низким динамическим диапазоном, которое получено путем Tone Mapping из изображения с высоким.

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

                                Так что и в фотографии, и в трехмерной графике этот термин относится к одному и тому же (если не учитывать его безграмотное употребление), только получаются составляющие этого процесса по-разному.
                                  –2
                                  Всё правильно, только в играх tone mapping специально (зачем-то) выдаёт результат как хиленький LDR кадр, а в фото основная цель tone mapping — не допустить пересветов и теней при проявке многобитног hdr.
                            0
                            Было интересно почитать)

                            Немного не по теме, но скажу вот что — с эстетической точки зрения HDR выглядит хорошо, но с точки зрения геймера — он часто раздражает. Да и совсем не прибавляет реалистичности.

                            Я думаю, дело в том, что хотя это и верно,
                            В реальном мире, при нахождении в первой комнате — мы адаптируемся к этому освещению, при входе в другую комнату мы адаптируемся к другому уровню освещения.
                            в реальном мире мы можем находиться в темной комнате, и смотреть в светлую. При этом наше зрения адаптируется к освещенности небольшого светлого пятна, в которое мы смотрим. А вот в игре так не получается, поэтому вся реалистичность идет на смарку.
                              0
                              Просто у наших глаз огромный динамический диапазон. Он не достижим толком ни монитором, ни камерой.
                                +2
                                Динамический диапазон большой, да, мы можем видеть чуть ли не еденичные фотоны в темноте, можем смотреть на солнце прикрытое дымкой от небольшой облачности… Но не одновременно. На адаптацию к тем или иным условиям уходит какое-то время: должен расшириться/сжаться зрачок, измениться химический состав питания сетчатки глаза и так далее. А настоящий динамический диапазон — это количество градаций яркости которые мы можем различить одномоментно.
                                  +1
                                  С этим согласен. Но реальный человеческий глаз почти никогда не дает классического белого окна без деталей на фоне нормально освещенной комнаты. Видим и комнату и детали за окном. Точный диапазон одномоментный явно шире, чем у техники.
                                    0
                                    Тут есть одна тонкость — наш глаз способен адаптировать чуть ли не каждый «пиксель» (точнее, светочувствительный элемент — колбочки и палочки) по-отдельности. Кроме того, они из коробки обаладют разной светочувствительностью (никогда не замечали, что в темноте боковым зрением могут быть светлые пятна, а если смотреть на них напрямую — уже их не видно. Это из-за того, что палочек больше, чем колбочек именно в переферийном зрении, а они более чувтсвительны к яркости).

                                    И самое интересное — за глазами есть мозг, который адаптивно подстраивается под освещение сам. Кроме того, он очень уверенно дорисовывает то, в чем сомневается и не двоеряет глазам (классические иллюзии, типа когда светлая, но находящаяся в тени клетка кажется гораздо темнее, чем освещенная клетка).
                                      0
                                      Тут все просто. Колбочки — R,G,B элементы. Содержат йодопсины которые возбуждаются в определённой зоне с пиками на соответствующие длины волн. Палочки содержат родопсин, с пиком в зелёной части спектра. Связано с лесным образом жизни предков. Соответственно, чувствительность палочек выше, чем у колбочек. Центральное пятно, макула, содержит преимущественно колбочки. Поэтому мы хорошо замечаем движение в сумерках на периферии (хищник крадется) и не различаем толком цвет.
                                      Механизмов регуляции чувствительности по сути два:
                                      1) диафрагма-зрачок. От 8 до 1 мм примерно. Сужается мгновенно почти, расширяется несколько минут.
                                      2) обратимый распад родопсинов и йодопсинов под действием света. Поэтому нужно время на их синтез при переходе в тёмное помещение. Обычно около 10 минут на полную чувствительность.

                                      Аналогии с диафрагмой и ISO матрицы почти полные.
                                        0
                                        Спасибо за подробный ответ. В общем то не знал химический состав, в остальном вроде как это известная информация.

                                        Тем не менее, как раз второй механизм и позволяет делать чувствительность глаза неоднородную по «матрице» (сетчатке) глаза. Кроме того, она не просто может быть неоднородной, она неоднородная по обределению. Так или иначе её сглаживает уже мозг. Когда в камере светочувствительность каждого элемента одинаковая (в пределах погрешности). Более того, она заметно выше, чем у глаза (просто у мозга более совершенные методы сглаживания и не стоит забывать, что чем толще у вас пачка денег, тем большая светочувствительность матрицы. Бесспорно, глаз в условиях плохой освещенности может улавливать совсем небольшое количество фотонов, но чем ярче точка, тем хуже чувствительность к отдельно взятым фотонам, в камере же чувствительность стремится быть линейной). Что-то я увлекся и начал играть в КЭПа.

                                        Хотел добавить, что есть еще один очень важный механизм, который в камерах пока не удается сделать качественно — наш мозг, который как раз и выравнивает освещенность и позволяет видеть больше и лучше, чем, собственно, видят наши глаза. Вот возьмем пример — отражение от темной поверхности. Пока мы смотрим на него глазами, нам кажется, что оно имеет примерно такую же яркость, как и оринигал, мы можем абстрагироваться и работать с отражением будто бы мы смотрим непосредственно на то, что отражается. А теперь сделаем фотографию и посмотрим на уровни яркости в цифровом виде. Не сложно убедиться, что отражение будет тусклее. И это не магия в глазах (матрице), а магия в мозге (вычислительном процессоре).

                                        Сюда же относится то, что все любят говорить, что смотреть на монитор, который испускает прямой яркий свет вредно. Но если сравнить яркость монитора и яркость неба в солнечный с легкими облаками день если померять фотометром — монитор и близко не стоял.
                                          0
                                          Вообще это я все к тому, и, думаю, со мной все согласятся, что нужно не пытаться сэмулировать поведение глаза и мозга, а наоборот — пытаться подсунуть ту картинку, которую бы выдел игрок, окажись он на месте камеры. А зрение человека уже само разберется с эффектами. Как это сделать — другой вопрос.
                                            +1
                                            Согласен с вами полностью) вообще мозг офигеть как кадры дорисовывает. Весьма здоровое слепое пятно мы не замечаем, даже если смотрим одним глазом. Трещина на стекле очков, выпавший участок сетчатки почти нивелируются, если времени прошло достаточно и объём потерянного изображения не критичен.
                                  0
                                  Не совсем. Одновременно одинаково хорошо видеть и яркие, и темные объекты мы не можем. Дело как раз в том, что человеческий глаз может подстроиться, и выбрать тот поддиапазон освещенностей, который человеку в данный момент интересен. И не всегда этот диапазон соответствует средней яркости сцены.
                                0
                                Мне было бы интересно почитать по 2D-шные финты. В Rayman Legends, например, любопытное освещение и прочие фичи, про реализацию которых было бы интересно узнать.
                                  0
                                  Про 2D-шные финты писал тут, тут и тут.
                                    0
                                    Я про вот это: UbiArt Engine Explored (ну и до этого момента любопытно, там построение земли со всеми потрохами по линии).
                                      0
                                      Каждый раз, когда смотрю видео про Ubiart Engine, начинаю люто бешено завидовать. Спасибо :).
                                        0
                                        Это да… Что ведь забавно — до видео-роликов добралась лишь малая толика всех фич, полный список которых даже не перечислен нигде. Страшно подумать, какое слюноотделение было бы тогда…
                                  +7
                                  Простите, а что имеется в виду под словами «а Unity так вообще движок-песочница»?
                                    +1
                                    Было интересно почитать Ваши аргументы насчет XNA, хотелось бы более детального рассмотрения почему оно еще останется применимым года 2-3. Т.е. какие-то массовые факты, примеры движков и игр. Спасибо!
                                      0
                                      Сейчас работаю над движком для рендеринга отснятых 360-градусных панорам в браузере на javascript через WebGL (используя three.js). Очень хочется реализовать HDR, но толком не знаю, как к нему подступиться. Шейдеры в движке уже используются (для создания эффекта виньетирования), но непонятно, как хранить HDR-текстуры, и как эффективно высчитывать среднюю освещенность кадра на WebGL. Был бы рад за подсказку, в каком направлении копать :)
                                      +2
                                      По поводу второго заключения:
                                      Хабр — это огромная площадка, ее аудитория далеко не ограничена захабренными пользователями. Я думаю, здесь ваши посты увидят больше интересных с профессиональной точки зрения людей.
                                      У меня были подобные вашим размышления, когда я публиковал материалы по программированию аудио. Шестнадцать объемных статей породили два полезных обсуждения размером в 4-5 комментов, большая часть из этих статей еле поднялась над нулем.
                                      Однако, тематика непосредственно связана с IT, материал нишевый и качественный, и на Хабре ему самое место. Активная аудитория со временем подтянется. Хочется верить :) Да, нужно признать, что некоторые ниши у нас совсем не развиты. Флаг в руки :)
                                      И кстати: мой цикл публикаций в результате свел меня с очень интересными людьми в оффлайне, которые не зарегистрированы на Хабре, но нашли способ со мной связаться.
                                        0
                                        Этот топик реально читают. По моей ссылке из незаплюсованного комментария где-то в гуще обсуждения прошло больше 300 тел (но пока меньше 1000). Разница в количестве зарегистрированных на Хабре и простых читателей огромна.
                                        +1
                                        Откуда картинка с девочкой?
                                          0
                                          Да вообще, будьте добры ссылки на все используемые модели и ресурсы, ежели из Public Domain.
                                          0
                                          Ну и контрастность сцены в целом (слева HDR, справа LDR):

                                          Весело Вы сравниваете. Слева и небо есть, и земля не вклеточку, и (что самое главное) текстуры детализированные, в том числе и нормалей.
                                            0
                                            Отнюдь. Размеры текстур те же самые. И у второй нет спекуляра.
                                              0
                                              Морщины на лбу — слева есть, справа нет. Брови — слева есть, справа нет. Модель освещения тоже определённо другая.
                                                0
                                                Судя по ступенчатой тени и алиасингу, справа не рендер, а превью.

                                            Only users with full accounts can post comments. Log in, please.