для приведения хдр в лдр
Mr F
> Мне ACES не нравится двумя вещами - сильно искажает цвета и при этом очень
> мудрёный.
Вот немного информации и сравнений ACES тонирования с обычным (по сути, из Uncharted 2): ссылка
Явно видны преимущества над прочими методами тонирования, да и реализация не такая уж и мудрёная.
Вот код, вдруг кому пригодится:
Daniil Petrov
Как тебе уже ответили в отдельной теме, их нужно использовать вместе, причём тонирование обязательно должно проводиться в линейном пространстве.
Загружаем текстуры с флагом sRGB (либо самостоятельно проводим конвертацию в шейдере), рассчитываем освещение и возвращаем результат в линейном пространстве. Далее передаём получившуюся текстуру на этап пост-обработки, применяем тонирование, а затем переводим в пространство монитора (вполне подойдёт sRGB, но можно добавить поддержку Gamma 2.2, Rec 709, HDR форматов: ACES 1000nit, 2000nit):
float3 LinearToSrgb(float3 lin) { lin = max( 6.10352e-5, lin); return min( lin * 12.92, pow( max( lin, 0.00313067), 1.0/2.4) * 1.055 - 0.055); } float4 FinalPassPS( float2 texCoord : TEXCOORD0) : COLOR { float3 linearColor = tex2D( mainSampler, texCoord).rgb; linearColor = ... // Добавляем DoF, Bloom, Vignetting и т.п float3 filmColor = FilmToneMap( linearColor); float3 outDeviceColor = LinearToSrgb( filmColor); return float4( outDeviceColor, 1.0f); }
Для оптимизации записывать результат тонирования и цветокоррекции лучше в небольшую LUT текстуру (32x256 пикселя), а затем использовать её в финальном проходе.
После тонирования и перевода в пространство монитора, можно применить эффект Dithering для минимизации бандинга. Реализацию можно найти у Unity Technologies:
https://github.com/Unity-Technologies/PostProcessing/blob/v2/Post… /Dithering.cs
https://github.com/Unity-Technologies/PostProcessing/blob/v2/Post… ithering.hlsl
ENAleksey
> Вот код, вдруг кому пригодится:
А это вообще что за код? Ни плюсы, ни GLSL его не понимают :)
Daniil Petrov
> А это вообще что за код? Ни плюсы, ни GLSL его не понимают :)
как насчет HLSL?
MrShoor
Увы :) никак!
> А это вообще что за код? Ни плюсы, ни GLSL его не понимают
PA3UJIb
Я что-то делаю не так?
Скорее всего, нужно изменить порядок перемножения вектора на матрицу.
Например, вместо этого:
vec3 WorkingColor = sRGB_2_AP1 * LinearColor;
Делать так:
vec3 WorkingColor = LinearColor * sRGB_2_AP1;
И попробовать вместо этих матриц:
const mat3 sRGB_2_AP1 = XYZ_2_AP1_MAT * D65_2_D60_CAT * sRGB_2_XYZ_MAT; const mat3 AP1_2_sRGB = XYZ_2_sRGB_MAT * D60_2_D65_CAT * AP1_2_XYZ_MAT;
Использовать эти:
const mat3 sRGB_2_AP1 = mat3(0.61319, 0.33951, 0.04737, 0.07021, 0.91634, 0.01345, 0.02062, 0.10957, 0.86961 ); const mat3 AP1_2_sRGB = mat3( 1.70505, -0.62179, -0.08326, -0.13026, 1.14080, -0.01055, -0.02400, -0.12897, 1.15297 );
ENAleksey
Получается вот так:
Daniil Petrov
Нужно изменить все строки, где происходит умножение вектора на матрицу.
Алгоритм, который Алексей привёл, выдерживаешь?
1. Получить цвет как sRGB.
2. Перевести из sRGB в линейный цвет.
3. Выполнить расчет освещения и постфильтрацию.
4. Выполнить тонирование.
5. Перевести цвет обратно из линейного пространства в sRGB.
6. Вывести результат.
Daniil Petrov
Возьми код отсюда:
https://gamedev.ru/code/forum/?id=230008&page=2#m21
И замени это:
vec3 ToneColor = vec3 (lerp ( ToeColor.r, ShoulderColor.r, t.r ), lerp ( ToeColor.r, ShoulderColor.g, t.g ), lerp ( ToeColor.r, ShoulderColor.b, t.b ));
На это:
vec3 ToneColor = vec3 (lerp ( ToeColor.r, ShoulderColor.r, t.r ), lerp ( ToeColor.g, ShoulderColor.g, t.g ), lerp ( ToeColor.b, ShoulderColor.b, t.b ));
А ещё лучше, на это:
vec3 ToneColor = mix(ToeColor, ShoulderColor, t);
То, что я писал про матрицы, делать не надо.
PA3UJIb
> Алгоритм, который Алексей привёл, выдерживаешь?
1) Гружу текстуры как sRGB.
2) Включаю GL_FRAMEBUFFER_SRGB.
3) При выводе финальной картинки в буфер кадра пропускаю outputColor через тонирование.
А как полностью контролировать весь процесс, описанный выше?
ENAleksey
> И замени это:
Картинка слабо меняется :)
Daniil Petrov
И это замени:
ToneColor = vec3 (lerp ( dot ( ToneColor, AP1_RGB2Y ), ToneColor.r, 0.93 ), lerp ( dot ( ToneColor, AP1_RGB2Y ), ToneColor.g, 0.93 ), lerp ( dot ( ToneColor, AP1_RGB2Y ), ToneColor.b, 0.93 ) );
На это:
ToneColor = mix(dot( ToneColor, AP1_RGB2Y), ToneColor, 0.93);
Тема в архиве.