Кстати, советую посмотреть это видео о тонировании и цветокоррекции, в котором объяснено, почему ACES Tonemapper так важен:

Справа просто загрузка, слева pow(c, 2.2), пока через шейдер, рескейл отключен.
Тоже самое, но с включенным рескейлом.
Тоже самое, но уже и с рескейлом, и твоей функцией.
Так, возможно я не правильно гружу hdri, по тому что более приятный цвет получается без какой либо модификации его цветового пространства.
Короче, я уже не понимаю ничего.
фулрез с рескейом и твоей функцией
vindast
Выгрузи уже несколько скриншотов до цветокоррекции. В линейном пространстве в rgba16f с помощью графического дебагера. В dds формате.
MrShoor, renderDoc умеет?
vindast
> MrShoor, renderDoc умеет?
Да, умеет:

Вот что будет если саму пикчу пережать на этапе загрузки.
Так что все было в порядке.
MrShoor, сейчас сделаю.
MrShoor, он отваливается при попытке сохранить текстуру.
Могу залить капчу самого кадра. Там будет по 350 мб каждая)
MrShoor не хочет он сохранять half
RDOC 007024: [23:37:07] dds_readwrite.cpp( 546) - Error - Unexpected component byte width 2 for 3-component type RDOC 007024: [23:37:07] dds_readwrite.cpp( 696) - Error - Couldn't convert resource format to DXGI format
В .hdr сохраняет. Если есть чем открыть то скину.
vindast
Внутри оказалось 2 файла. Один называется:
"без перевода в линейное пространство"
Второй называется:
"переведен в линейное пространство".
Второй файл странный... и я думаю ты запутался что есть где.
Линейное пространство - это такое пространство, где свет от источников света ты можешь спокойно складывать: A + B + C. Все освещение должно делаться в линейном пространстве.
А уже после, при выводе на монитор его переводят в sRGB пространство. У тебя как-то все наоборот, ты зачем-то переводишь в линейное пространство.
Первая картинка, которая называется: "без перевода в линейное пространство" - похожа на картинку с линейным пространством. То есть то, что выдает твой рендер без всяких телодвижений.
Вторая картинка - я вообще хз что это... Такое ощущение, что ты трактовал первую картинку как sRGB, и попытался перевести в линейное пространство еще раз. Короче вторую картинку, которая "переведен в линейное пространство" я даже не рассматривал.
Далее семпл с тонмаппингом. Собранный пример можно посмотреть тут:
https://drive.google.com/drive/folders/1acI1BZ0ms5Nsj9uVj75xz_rPibY4KJ4x
Радобаттонами можно менять тип тонмаппинга, а трекбаром крутить экспозицию. Пример грузит linear.hdr, который лежит рядом с экзешником.
Код шейдера:
В качестве Reinhard-а был взять классическая формула x / (x+1). Проще некуда.
В качестве ACESFilm был взят код, который приводил тут ENAleksey
В качестве Uncharted2 был взят код отсюда: http://filmicworlds.com/blog/filmic-tonemapping-operators/
Все тонмаппинги выглядят примерно так, как я и ожидал. Тебя устраивает какой либо из этих результатов?
MrShoor, Вы не поняли. Я по просьбе ENAleksey загрузил hdri как srgb, и перевел ее в линейное.
На скринах как раз видно что при переводе картинка будет "завалена".
MrShoor
> Тебя устраивает какой либо из этих результатов?
Uncharted2 и ACESFilm хороши. Вот что получается с Uncharted2 и ACESFilm
И тот и тот вариант с рескейлом:
#version 440 core
in vec2 TexCoords;
out vec3 color;
uniform sampler2D screentex;
uniform sampler2D flare;
uniform sampler2D lensderttexture;
uniform sampler2D anamorphicMap;
uniform sampler2D lensstarbursttexture;
uniform sampler2D ssaoTex;
uniform mat3 uLensStarMatrix;
uniform sampler2D emmisiveTexture;
uniform float averageColor;
uniform float hdrCompressionKoef;
float rgb2luma(vec3 rgb)
{
//Взвешивает цвет в grayscale (яркость пикселя), находит яркость пикселя
//Если у вас не линейное простраство света то
//rgb нужно перевести в линейное пространство
return dot(rgb, vec3(0.2126, 0.7152, 0.0722));
}
vec3 getHDR(vec3 color)
{
float x = exp(averageColor);
float L = (hdrCompressionKoef / x) * rgb2luma(color);
return color * (hdrCompressionKoef / x) / (1.0 / (1.0 + L));
}
#define float3 vec3
float3 ACESFilm(float3 x)
{
float a = 2.51f;
float b = 0.03f;
float c = 2.43f;
float d = 0.59f;
float e = 0.14f;
return (x*(a*x+b))/(x*(c*x+d)+e);
}
float3 Uncharted2Tonemap(float3 x)
{
float A = 0.15;
float B = 0.50;
float C = 0.10;
float D = 0.20;
float E = 0.02;
float F = 0.30;
return clamp(((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F, vec3(0), vec3(1));
}
float3 Uncharted2TonemapFull(float3 x) {
float3 curr = Uncharted2Tonemap(x);
float W = 11.2;
float3 whiteScale = 1.0f / Uncharted2Tonemap(vec3(W));
return curr*whiteScale;
}
void main()
{
color = texture(screentex, TexCoords).rgb;
color = getHDR(color);
color = ACESFilm(color);
if(gl_FragCoord.x > 1000)
{
color = Uncharted2TonemapFull(color * 2.0);
}
}vindast
Вот смотрю я на твои скрины, и у меня стойкое ощущение, что ты выводишь результат сразу после тонмаппинга, без перевода в sRGB, все дико чернушное.
Потом я смотрю твой код шейдера, и не вижу после тонмапа:
color = pow(color, 1.0/2.2);
И у меня еще больше уверенности, что ты не переводишь в sRGB пространство...
Но ты бьешь себя в грудь, и говоришь, что у тебя все нормально. Ну ок, чо.
Ты просто ради интереса возьми, и сравни свои скрины с тем, что выдает моя демка. А потом добавь последней строкой в шейдере color = pow(color, 1.0/2.2);, и снова сравни.
MrShoor
> В качестве ACESFilm был взят код, который приводил тут ENAleksey
А разве ACES не выдаёт сразу гамма-закодированные величины?
Тема в архиве.
Тема закрыта.