Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rtx: physically correct emissive textures remaster #267

Closed
w23 opened this issue Dec 8, 2021 · 35 comments
Closed

rtx: physically correct emissive textures remaster #267

w23 opened this issue Dec 8, 2021 · 35 comments
Labels
bug Something isn't working materials ray tracing visual bug Visual glitches, something looks incorrectly

Comments

@w23
Copy link
Owner

w23 commented Dec 8, 2021

Currently we'll draw emissive surfaces similar to how it operates for original renderer:

  • treat them as very high constant color for emissive lighting purposes
  • draw texture as is w/o lighting for direct hit from camera

More physically correct path tracer would have the same color sample value for both direct hit and emissive light ray samples. That required emissive texture remaster though:

  • regular set of pbr textures (will be sampled for non-emissive areas of the surface)
  • emissive mask (which area is emissive)

Lighting code would then need to properly sample this:

  • zero emitted light from non-emissive parts (easy)
  • sampling strategy to prefer emissive parts (hard)
@w23 w23 added bug Something isn't working ray tracing visual bug Visual glitches, something looks incorrectly labels Dec 8, 2021
@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 9, 2021

Есть несколько важных проблем которые мешают.

  1. Эмиссив обрабатывается как-то неправильно, любая текстура к которой оно применено становится блёклой как ни крути, в каком пространстве работает payload.emissive?
  2. Совершенно нарушен kusok.emissive который уже при 20 отчётливо белый, даже при 1 он заметен.
    +0~LAB1_CMP2 255 255 255 20 в c1a0.rad покрути, комп который в углу в самом начале.
    Интересно то что если включить режим только света (r_lightmap 1), то при 1 кусок вовсе в темноту уходит!
    изображение
    Отрицательное освещение при 1? (заметно уже с ~7). Но без r_lightmap 1 оно просто серым отдаёт.
    Пока ты не поправишь эти косяки остальные рассуждения бессмысленны.

@w23
Copy link
Owner Author

w23 commented Dec 10, 2021

  1. Так а это именно то, чего ты хотел, и про что я тебе говорил! Там сейчас emissive вообще не учитывается. То есть он учитывается бинарно: если 0, то поверхность участвует в освещении как обычно, принимая свет. Если не 0, то мы рисуем просто цвет базовой текстуры безотносительно значения emissive, и поверхность сама по себе не участвует в освещении и не принимает свет (она участвует как источник со значением emissive, но это никак не влияет на то, как она выглядит сама).
  2. Там сейчас emissive куски не принимают на себя свет. То есть для значения 1 он просто тупо очень тусклый, а поскольку других способов ему получить свет нету, то это именно тот цвет, которым он рисуется.

Попробую собрать с масками и посмотреть:

  • где маска 0 поверхность обычная: принимает свет, но не излучает.
  • где маска 1 поверхность излучающая: не принимает свет, но излучает с emissive * base_color.

Возможно, даже с 1 она должна принимать свет, но это надо пробовать.

w23 added a commit that referenced this issue Dec 10, 2021
@w23
Copy link
Owner Author

w23 commented Dec 10, 2021

Сделяль: #274
c1a0d_shot0001
c1a0d_shot0002

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 10, 2021

@w23 маски ты молодец что сделал и я думаю они пригодятся, но они не решают данные проблемы.

  1. нет ты не понял, я вручную тыкал в шейдере payload.emissive, например если туда загнать base_color и чтобы с ним не делать он всё равно будет с убитой глубиной. То есть смешивание с самим base_color проходит плохо. Сейчас ещё одну идею проверю.
  2. я не понял что ты этим хотел сказать. Смотри как я это вижу, вот есть kusok.emissive он там у тебя нормализуется (на самом деле это костыль маскирующий проблему) и умножается на base_color итого получается светящаяся примерно похожая на оригинал текстура, но проблема с компом который мигает заметно светлым остаётся! Почему остаётся? потому что kusok.emissive рассчитывается совершенно неверно! он становится светлее даже раньше чем это делает курад!
Вот доказательство с test_light

На самом слабом сурфейсе с 10 яркостью (на 1 я не делал так, но он точно не будет светиться так как у тебя светится):

изображение
изображение

Получается у тебя ещё менее физически корректно чем у курада.

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 10, 2021

Далее вопрос между делом, у нас https://github.com/w23/xash3d-fwgs/blob/vulkan/ref_vk/vk_ray_model.c#L400-L402 подразумеваются эмиссивные материалы? то есть потенциально я смогу ещё загрузить карту для свечения? (хотя по идее то же самое решается через маску где серая зона пол силы источника света), но для моделей это бы было хорошая штука где нельзя задать свечение иначе.

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 10, 2021

Теперь ещё раз по первому пункту:

Смешивание происходит так что на выходе у нас серный цвет вместо белого

изображение
Для сравнения как должно быть:
изображение

Чтобы быть точнее я создал тестовую карту test_gradient с градиентами

изображение
изображение
На base_color градиенты у нас кстати в RTX отображаются заметно корректнее.

изображение
изображение

Как видно белый убит и градиент в целом едет на emissive текстурах по сравнению с base_color.

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 10, 2021

Для теста сделал без всяких условий:

	payload.base_color = vec3(0.,0.,0.);
	payload.emissive = base_color;
Мы в серой комнате:

изображение

Куда же пропал белый?

Возможно это немного поможет, если я делают так:

	//const vec3 base_color = ((push_constants.flags & PUSH_FLAG_LIGHTMAP_ONLY) != 0) ? vec3(1.) : tex_color.rgb;// pow(tex_color.rgb, vec3(2.));
	const vec3 base_color = pow(tex_color.rgb, vec3(2.)); // можно в payload.emissive сделать это же с тем же успехом
то равномерность градиента возвращается в случае с emissive на примере выше, но сам белый цвет нет

изображение

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 10, 2021

Муторно пробежавшись по отчасти запутанному коду понял что ты это рисуешь как out_additive.
То есть весь пасс с emissive текстурой это повторение additive эффектов, дальше там вылезают проблемы:
в additive.rahit где

payload_additive.color += color * smoothstep(additive_soft_overshoot, 0., overshoot);
ignoreIntersectionEXT; // это тоже несёт серость

в ray.rgen где

	payload_additive.color = vec3(0.);
	payload_additive.ray_distance = ray_distance;
	traceRayEXT(tlas, flags, GEOMETRY_BIT_ADDITIVE,
		sbt_offset, sbt_stride, SHADER_OFFSET_MISS_EMPTY,
		origin, 0., direction, ray_distance + additive_soft_overshoot,
		PAYLOAD_LOCATION_ADDITIVE);
	return payload_additive.color * color_factor;

Всё это убивает глубину.
Я считаю emissive текстуры надо обрабатывать отдельно от additive спрайтов (которые тоже сероваты, но там это с пивом потянет, хотя вспышки без HDR не кажутся такими какими должны быть, например вот такая серая фигня вместо искры). А ещё надо иметь ввиду что в additive оттенки чёрного у basecolor является полупрозрачным.
Как чинить не знаю, тут уже опыта и знаний этих штук не хватает.

Теперь вопрос где kusok.emissive рассчитывается?

@0x4E69676874466F78
Copy link
Collaborator

Залил test_gradient #33 (comment)

@w23
Copy link
Owner Author

w23 commented Dec 11, 2021

Давай определимся сначала, какого мы хотим добиться эффекта. Например, варианты:

  1. Светит всей поверхностью "как в кураде", выглядит "как в растеризаторе".
  2. Светит всей поверхностью "как в кураде", выглядит по маске: так же, как светит где 1, "как в растеризаторе" где 0.
  3. Светит всей поверхностью "как в кураде", выглядит так же, как светит: всей поверхностью.
  4. Светит маской/текстурой, выглядит так же, как светит.

Варианты (1 и 2) нефизичные, надо специально хачить: . Будет выглядеть криво: поверхности рядом с источником света ненатурально яркие по сравнению с самим источником.
Вариант (3) выглядит стрёмно: теряем текстуры ламп и прочего.
Вариант (4) должен быть ок, но (а) надо всё ремастерить, (б) надо правильно экспонировать и тонмапить хдр. Источники света очень яркие по сравнению со всем вокруг, и это вроде как норма (по крайней мере другие трассировщики ведут себя так же).

В целом, я считаю что у меня проблемы с:

  • пониманием, в каком цветовом пространстве должны быть текстуры
  • тонмаппинге и хдр/экспозиции

Я предлагаю:

  1. Я сделаю именно (4): умножение цвета и для вывода, и для свечения на base_color.
  2. Мы пока забьём на то, как именно выглядят сами источники.
  3. Я покручу цветовое пространство и пойму, как там всё должно быть.
  4. Будем крутить экспозицию и ремастерить текстуры источников и маску, блум может всякий добавим.

@w23
Copy link
Owner Author

w23 commented Dec 11, 2021

Вот несколько вариантов игры с экспозицией и тонмаппингом.
Не привожу подробности настроек не только потому, что не помню их, но также и потому, что они все абсолютно некорректные и тупо на глаз очень.
test_gradient_shot0004
test_gradient_shot0005
test_gradient_shot0006
test_gradient_shot0007
test_gradient_shot0008

@w23
Copy link
Owner Author

w23 commented Dec 11, 2021

А, да, про additive: канал additive существуе только для того, чтобы добавлять цвет без шумодава и перемножения. Потому что у нас есть отдельно каналы альбедо и шумного освещения диффузов со спекулярами. Они шумодавятся и перемножаются друг на друга, тогда как аддитив просто добавляется, как есть (перед тонмаппингом, кончено).

Это корректный способ добавить эмиссив, потому что он не имеет отношения к диффузоспекулярному освещению.

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 11, 2021

Так из-за чего additive был серым? если убрать тонемаппинг серость не уходит. Где это настраивается?

какого мы хотим добиться эффекта

Красивого. Ну по возможности в рамках правдоподобного.

План такой:

  1. Нужно чтобы после всех операций в SDR/LDR белый цвет из сцены был белым на экране. Сейчас если яркость лучей близка 255 белому, на test_light4 можно увидеть что 252 (99% в 8бит) белого у лучей, то яркость эммисив текстуры (без учёта твоих экспериментов на скриншотах выше) совершенно неправильная (ну не может она быть серой когда лучи окрашивают рядом белым), где должно быть 100% 255 белого там 173 (68% в 8бит) белого (сама текстура 255 100% белая).
    Данный пункт касается ТОЛЬКО ПОЛНОТЫ выдаваемого цвета на экран LDR/SDR монитора. Потому что сейчас выходит так что мы вместо 255 для эммистив текстур упираемся в максимум ~173.
  2. Откорректировать расчёт kusok.emissive, сейчас он заставляет быть очень светлой текстуру которая фактически толком не светит, он непропорционально яркий (не соответствует вкладу лучей в сцену). Это уже ДРУГАЯ история.
    И вот здесь мы приходим к теме физической корректности, потому что как понимаю kusok.emissive считается от силы лучей так? Там те же значения что и идут для испускания лучей?
    Физически корректная эммисив текстура не может быть тусклее чем поверхность окрашенная лучами испускаемые от неё, она всегда ярче.
    Я сделал наколеночный ублюдочный тест (не нашёл быстро каких-то нормальных тестов на эту тему), для грубой оценки, чтобы вообще понимать насколько там велика разница. Взял экран смартфона, выставил яркость на максимум, выставил белый фон, приложил к листу бумаги (условно шероховатая поверхность) и во втором случае приложил к зеркалу, сфоткал на второй смарт, получилось максимально дерьмово, белый на фото я не получил, но примерную разницу узнал.
    Разница в случае с максимальной шероховатостью от 1,71 до 2,35 раза, в случае с зеркалом от 1,17 до 1,32 раза.
    Если не найдём ничего лучше, то предлагаю взять что-то среднее из этого, чтобы просто не выбиваться далеко от физической корректности.
    Следовательно в типичной сцене текстура ламп должна иметь цвет в 2 раза больше (пусть она умножается на себя саму) чем лучи которые мы видим от неё рядом, но если источник рядом с зеркалом разница относительно света от лучей падает до 1,25 раза. Короче добиться чтобы на белом полу с roughness 1, светящаяся текстура была в 2 раза ярче чем свет от неё на полу.

Для отладки надо:

  1. в консоли крутилку для экспозиции (настоящей, а не хакованной), если запилить целиком Dynamic/auto exposure #193 сейчас не реально. Нам сейчас хотя бы базовую экспозицию правильно выставить на тестовых сценах.
  2. вывод какое значение силы источника света (из rad файла) какому значению kusok.emissive соответствует.
  3. узнать при каком значении payload.emissive текстура будет иметь вид base_color с полной яркостью (как если на неё смотреть без какого-либо освещения), например подаём белую (255 255 255) текстуру, крутим пока она там не станет 255 255 255 при нашей базовой экспозиции.
  4. желательно добавить в ui_infotool значение яркости (в R G B) пикселя под прицелом в том цветовом пространстве в которым мы находимся.

Просто нельзя исключать что kusok.emissive содежит в себе значения не пригодные для пространства payload.emissive, что нормализация тут лишь маскирующий костыль и недостаточна, а возможно нужно ещё пропустить через какую-то кривую-коррекции, потому что сейчас даже после нормализации низкие значения слишком сильны и предварительно они сильнее чем то что я получаю на наколеночном тесте, но тут ещё мешает беда с 1 пунктом, поэтому пержде чем подходить к 2 нужно исправить 1 пункт плана.

Без масок мы действительно никуда не денемся, но для масок нам нужен блум эффект, иначе невозможно это оценивать даже с художественной точки зрения (не говоря уж о физ корректности).
Я кстати сделал два вида масок резкие и с некоторым сглаживанием, сглаживание будет работать или это воспринимается как монохромная карта?

Сейчас сделаю ещё одну сцену (test_light5) где у нас будут комнаты для отладки всего этого.
Сделаю чтобы белый был 255 на полу и посмотрю что там у нас.
Базовую экспозиция надо подогнать под освещение курада на test_light3.

В целом мне нужны крутилки, тогда бы я мог выкрутить освещение согласно всем тестам при этом не сломав игру.

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 11, 2021

Добавил в \valve\luchiki\maps\c1a0.bsp.patch:

{
"_xvk_ent_id" "14"
}
{
"_xvk_ent_id" "42"
}
{
"_xvk_ent_id" "43"
}
{
"_xvk_ent_id" "44"
}
{
"_xvk_ent_id" "45"
}
{
"_xvk_ent_id" "181"
}
{
"_xvk_surface_id" "761"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "762"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "249"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "248"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "742"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "740"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "744"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "428"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "28"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "192"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "749"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "750"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "748"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "430"
"_light" "0 0 0 0"
}
 {
"_xvk_surface_id" "576"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "575"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "577"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "573"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "574"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "571"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "572"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "570"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "568"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "567"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "569"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "564"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "565"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "566"
"_light" "0 0 0 0"
}
 {
"_xvk_surface_id" "645"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "623"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "618"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "350"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "351"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "359"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "26"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "190"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "1670"
"_light" "0 0 0 0"
}
{
"_xvk_surface_id" "1676"
"_light" "0 0 0 0"
}

Загрузился с #274 на c0a0.
Вот что вижу

Half-Life.2021-12-11.19-06-11.mp4

Поэтому у меня есть сомнения на тему правильности вклада kusok.emissive.

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 11, 2021

{
"_xvk_surface_id" "318"
"_light" "255 255 255 0.30"
}

Вот так будет соответствовать примерно base_color без освещения, но с убитой глубиной.

{
"_xvk_surface_id" "318"
"_light" "255 255 255 100"
}

А вот так на глаз ожидаемый свет от такой яркости текстуры как на видео.

Причём если я задам значение из rad файла:

{
"_xvk_surface_id" "318"
"_light" "255 255 255 20"
}

я получу ещё ярче текстуру. То есть то что в раде и то что в патче почему-то отличается при одних и тех же значениях.
Кстати там ломается анимация при патче (ну понятно почему), но это пока не существенно.

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 11, 2021

Обнаружил интересную особенность.
Загрузился потестить https://github.com/0x4E69676874466F78/xash3d-fwgs/tree/cmd
А там при

{
"_xvk_surface_id" "318"
"_light" "255 255 255 20"
}

изображение

Вполне себе корректное поведение! (за исключением проблемы глубины текстуры)
А вот если убрать и оно начинает мигать там уже не очень корректное.
Что-то не так с анимационными текстурами в контексте освещения. От них свечение виднеется но оно какое-то не то (едва заметное на видео, может видео врёт? почему-то между кадрами).

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 11, 2021

изображение
Вот сделал скрин с видео, видно что у анимационной текстуры всё же есть какое-то свечение.

@w23
Copy link
Owner Author

w23 commented Dec 18, 2021

1. Нужно чтобы после всех операций в SDR/LDR белый цвет из сцены был белым на экране. Сейчас если яркость лучей близка 255 белому, на [test_light4 можно увидеть](https://user-images.githubusercontent.com/4449851/145676523-94e2363d-7b2e-4e9d-9d8a-14f12942da6c.png) что 252 (99% в 8бит) белого у лучей, то яркость эммисив текстуры (без учёта твоих экспериментов на скриншотах выше) совершенно неправильная (ну не может она быть серой когда лучи окрашивают рядом белым), где должно быть 100% 255 белого там 173 (68% в 8бит) белого (сама текстура 255 100% белая).
   Данный пункт касается ТОЛЬКО ПОЛНОТЫ выдаваемого цвета на экран LDR/SDR монитора. Потому что сейчас выходит так что мы вместо 255 для эммистив текстур упираемся в максимум ~173.

а. А где у нас лежит test_light4? в #33 его нет.
б. Там серый цвет из-за корявого emissive в vulkan ветке. Более "правильный" в ветке emissive_mask.

@0x4E69676874466F78
Copy link
Collaborator

а. А где у нас лежит test_light4? в #33 его нет.

Действительно, он туда не попал, я его только в конфу заливал.
Тогда пока вот: test_light4.zip

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 18, 2021

б. Там серый цвет из-за корявого emissive в vulkan ветке. Более "правильный" в ветке emissive_mask.

Насколько я понял, это ты просто замаскировал проблему.
По памяти помню что там у тебя чтобы был белый нужно подать слишком большое значение и/или там просто по глубине всё равно проёб.

Завтра сделаю карту где будет не только белый, но и случай с обычной текстурой.
Обрати внимание что у тебя небо так же кривое (пусть ты и захачил близко к оригиналу) в плане цветов из-за этой проблемы.

@w23
Copy link
Owner Author

w23 commented Dec 19, 2021

Там точно какой-то проёб, но я пока не понимаю, какой именно.
Есть известный проёб: все поверхности пилятся на треугольники, и освещение зависит от их количества и площади, что не ок. Не уверен, что это оно, но может быть и оно.

Как с этим связано небо я пока вообще не понимаю. emissive по идее (до pow-хака) тупо напрямую передаётся из текстуры в тонмаппинг без каких-либо трансформаций вообще, и, соответственно, должен выглядеть ровно так же, как выглядят остальные текстуры, если бы у них освещённость была единицей.
Может, там какой косяк при именно загрузке скайбокса, и скайбокс текстура действительно находится в линейном пространстве? Надо смотреть.

@w23
Copy link
Owner Author

w23 commented Dec 19, 2021

Если исправить треугольники, то освещение в среднем должно стать примерно в 2 и более раз ярче, может как раз тогда они будут ближе друг к другу? В emissive_mask поверхности выглядят явно светлее, чем они светят на окружающий мир (map test_light):

test_light_shot0001

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 19, 2021

все поверхности пилятся на треугольники, и освещение зависит от их количества и площади, что не ок. Не уверен, что это оно, но может быть и оно.

Это уже 4 проблема помимо payload.emissive, kusok.emissive, анимационные текстуры.
Давай так:

  1. Исправить проблему с треугольниками, это можно на test_brush2 с жижей проверить.
  2. Исправить payload.emissive чтобы нормальная глубина была, это можно сделать на скайбоксе чтобы у него без хака было правильно и тогда по идее должны починиться и другие emissive текстуры.
  3. Исправить kusok.emissive чтобы он был ближе к реальности (он как понимаю зависит от треугольников в том числе), это можно будет на test_light5 делать.
  4. Исправить анимационные текстуры.

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

Как с этим связано небо я пока вообще не понимаю. emissive по идее (до pow-хака) тупо напрямую передаётся из текстуры в тонмаппинг без каких-либо трансформаций вообще, и, соответственно, должен выглядеть ровно так же, как выглядят остальные текстуры, если бы у них освещённость была единицей.

Это не так, покажи мне на примере любой эммисив текстуры чтобы было прям 1:1 как с basecolor у тебя это не получится! будет обязательно сломанная глубина цвета/серого (у тебя градиент серого не равномерный когда ты доводишь точку белого на градиенте до реального белого в сцене).

Проблема с payload.emissive мне кажется в логике самого additive режима, но я не достаточно понимаю как это в реальности там работает (не хватает знаний всех этих режимов вулкана), возможно мешает то что он получается полупрозрачный всегда даже когда он с непрозрачной подложкой и эта полупрозрачность работает весьма странно что убивает глубину? Как реализован additive режим?

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 19, 2021

Поговорим о связи двух багов с payload.emissive и kusok.emissive и чуть больше о их природе на эмпиричном примере.

Загрузился в бранч emissive-mask, открутил aces_tonemap в denoiser.comp (вначале забыл 😿 и результаты получились не те и я сделал не правильные выводы, теперь переписываю всё это) это важно!, запустил test_gradient, перешёл в режим только света, отредактировал rad файл чтобы белый там был белым (255,255,255) если взять пипеткой с экрана.
Чтобы достигнуть 255 в режиме только света надо в рад файле задать

DEBUG_RAD        255 255 255  200
DEBUG_G_E        255 255 255  10
DEBUG_G_R_E      255 255 255  10
DEBUG_G_D_E      255 255 255  10
DEBUG_G_D_R_E    255 255 255  10
DEBUG_GC_E       255 255 255  10
DEBUG_GC_R_E     255 255 255  10
DEBUG_GC_D_E     255 255 255  10
DEBUG_GC_D_R_E   255 255 255  10

При этом градиенты выглядят практически как надо, точка белого на градиенте становится 254.
Однако при светимости 9 точка белого 229 229 229, а при 1 она 25 25 25 (на градиенте так же), при 2 51 51 51.
С payload.emissive в бранче emissive-mask при выпилинном тонемаппинге всё отлично! Белый действительно белый.

Чтобы разобраться с kusok.emissive для начала надо починить расчёт треугольников, возможно это автоматом это починит, но в целом нарастание происходит гораздо быстрее чем ожидается и внутри payload.emissive надо как-то по особому готовить kusok.emissive а не просто умножать на него.
Значение kusok.emissive которое получено от рад файла равным ~10 (при 255 255 255) можно считать пороговым для LDR режима payload.emissive в контексте поведения qrad, или где у emissive_mask чёрный цвет.

Прикладываю дополнительно результаты полученные при тонемаппинге (если не заметно этот пункт можно раскрыть, много текста).

Под конец белый очень тяжело рос, разница между 254 и 255 довольно большая. 255 получилось так:

DEBUG_RAD        255 255 255  200
DEBUG_G_E        255 255 255  205
DEBUG_G_R_E      255 255 255  205
DEBUG_G_D_E      255 255 255  205
DEBUG_G_D_R_E    255 255 255  205
DEBUG_GC_E       255 255 255  205
DEBUG_GC_R_E     255 255 255  205
DEBUG_GC_D_E     255 255 255  205
DEBUG_GC_D_R_E   255 255 255  205

Если задать 204 будет 254, а само 254 начинается с 145, причём что интересно получается 254 254 253! Откуда там 253? со 146 оно становится равномерно 254. На 143 равномерно 253 253 253.

При 255 255 255 kusok.emissive градиент сломан.
Какое же значение надо подать чтобы у текстуры не был завален градиент?
Если я делаю серым 128... а фиг я его сделаю, но по порядку:

  1. если в рад файле задам 1 то только свете получу 61 61 61, а на градиенте точка белого будет 60 60 60.
  2. если задам 2 то в только свете и на градиенте 98 98 98.
  3. если 3 то 126 126 126.
  4. если 4 то 147 147 147.
    Как видно белый нарастает очень неравномерно это и есть проблема с kusok.emissive, что 1 это уже 61, 2 это 98, 3 126, а чтобы получить 255 надо аж 205, очень непропорционально! Сильно сжато в низких значениях и расжато на высоких.

Но в то же время есть проблема с payload.emissive, его смешивание работает примерно таким образом: точка чёрного остаётся на 0 0 0 и на 205 светимости, а вот все остальные градации градиента очень сильно зависят от подложки (kusok.emissive), при 205 когда белый 255 на градиенте вся остальная градация была пересвечена, при 3 когда белый 126 недосвечена (потому что крайний белый берётся от подложки).
Короче получить правильный градиент на emissive невозможно при тонемаппинге.
Additive при нём на 1-255 работает со своеобразным смешиванием, подложка влияет на этот диапазон так что визуально она похоже больше на эффект смешивания в нормальных редакторах под названием freeze (вторым ближайшим color burn), в гимпе я таких режимов слоя похожих не нашёл, зато нашёл в крите, только работает в крите немного иначе и надо делать подложку не совсем белой, там ещё есть похожие фильтры под названием Penumbra B/D. Раз, два — вряд ли полезно будет, но всё же.

Тонемаппинг в текущей реализации ломает белый на эммисив текстурах.
Самое быстрое решение применять тонемаппинг ДО colour += imageLoad(src_additive, pix).rgb;.
В ином случае надо разобраться как применяют aces_tonemap в нормальных условиях, чтобы он не ломал глубину у emissive текстур, возможно он в принципе для такого случая не предназначался.
И всё равно прежде чем пытаться надо чинить kusok.emissive, но нужно понимать что после тонемаппинга на emissive те же самые цвета получить не получится никак, он сам по себе вносит коррекцию, но тут у меня есть небольшое подозрение что возможно aces_tonemap предназначен для одного из цветовых пространств aces и тупо из линейного мапить он будет не совсем так как ожидается, а если использовать какое-то aces-пространство то цвета будут как надо.

Вот тест на небе:
С убранным тонемаппингом на additive и убраным костылём для skybox (сделал просто payload.emissive = texture(skybox, gl_WorldRayDirectionEXT).rgb;) выглядит так:
изображение
В GL:
изображение

То есть победа!

Предлагаю:

  1. делать тонемаппинг до colour += imageLoad(src_additive, pix).rgb;.
  2. убрать костыль для неба payload.emissive = pow(texture(skybox, gl_WorldRayDirectionEXT).rgb, vec3(2.2)); заменив на payload.emissive = texture(skybox, gl_WorldRayDirectionEXT).rgb;
  3. разобраться с треугольниками чтобы заработала жижа как надо.
  4. разобраться с kusok.emissive внутри payload.emissive чтобы освещение нарастало пропорционально, payload.emissive при этом должна быть где-то в два раза ярче чем освещение лучей от неё на roughness 1.
  5. применять emissive_mask там где у нас пересвет, добавить блум который зависит от силы свечения.
  6. вклад анимационных текстур починить.
  7. подумать что делать с тонемапом для emissive в контексте я слышал в этом сезоне модно рендерить в ACEScg #262.

@0x4E69676874466F78
Copy link
Collaborator

Если подумать то там 255 * 10 = 2550, но VectorScale(etex->emissive, 0.1f, etex->emissive); значит 2550->255, вот и вся разгадка.
Только у источников-то отнюдь не 10, а 1000 и 10000 нормально бывает, потому и дикий пересвет.
Нельзя в payload.emissive класть как есть kusok.emissive! Подумаю как его можно отмасштабировать.

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 19, 2021

В настоящий момент payload.emissive где

  • vec3(1,1,1) это 255 255 255 на экране
  • vec3(0.5,0.5,0.5) это 127 127 127
  • vec3(0.1,0.1,0.1) это 25 25 25
  • vec3(0.05,0.05,0.05) это 13 13 13
  • vec3(0.01,0.01,0.01) это 2 2 2
  • vec3(0.005,0.005,0.005) это 1 1 1

Допустим надо чтобы из рада 255 255 255 1 = 1 1 1 в payload.emissive и на экране 255 255 255.
Сейчас 255 255 255 1 это vec3(25, 25, 25)? а надо было чтобы vec3(0.005,0.005,0.005).
Разница в 5000, но это без учёта * base_color. С учётом base_color надо просто разделить на 25 kusok.emissive типа:
payload.emissive = (kusok.emissive / 25) * base_color;
Тогда для test_light5:

DEBUG_L_10      255 255 255  255
+0~TNNL_LGT4    255 255 255  255

Сделает полностью закрашенную текстуру, а при 1 она будет 1 1 1.
Но есть вот какая подстава с 1 1 1, всё что меньше 255 будет иметь яркость меньше чем мы хотим.
Логика qrad такая что исходно он не освещает текстуру и она ведёт себя как обычная текстура, и только при определённых значениях она начинает окрашиваться ярче других.
У нас же payload.emissive при меньших значения делает текстуру ТЕМНЕЕ.
Надо поменять эту логику и забыть про 255, подогнав эмпирически светимость текстуры под испускаемые ей лучи.

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 19, 2021

payload.emissive = (kusok.emissive / 7) * base_color;
или если обрезать пересвет:
payload.emissive = clamp((kusok.emissive / 7), 0.0, 1.0) * base_color;
Вот так выглядит при текущих реалиях более корректно.
Однако проблема с уходом в затемнее относительно общего освещения я толком не решил и все костыли мне не понравились.
Эмиссионные текстуры после какого-то коммита стали игнорировать освещение вообще! на них посветить фонариком даже нельзя. Я это ещё по пузатым моника в вулкан бранче заметил. Это всё портит.
Сейчас поищу коммит виновник.

@0x4E69676874466F78
Copy link
Collaborator

#296

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 26, 2021

Сегодня чудным образом быстро разобрался в проблеме, но тут надо сказать ещё спасибо @MaxG2D так как после его бранча #302 до меня начало доходить как надо решать эту проблему.

Итак, у нас есть 3 слоя вклада света (световой пирог) + 4 слой бонуса.

  1. на бранче emissive-mask есть дополнительный вклад от payload.emissive.
  2. паразитный вклад находится в
const vec3 base_color = ((push_constants.flags & PUSH_FLAG_LIGHTMAP_ONLY) != 0) ? vec3(1.) : tex_color.rgb;
  1. лучевой вклад в
payload.hit_pos_t = vec4(hit_pos + geom_normal * normal_offset_fudge, gl_HitTEXT);

который нас ведёт в ray.rgen в sampleSurfaceTriangle.

  1. при этом ещё добавляется воздействие тонемаппинга если им неправильно пользоваться.

Чтобы получить очень похожий на qrad вид я сделал так:
в ray.rchit:

const vec3 base_color = vec3(0.); 
payload.emissive = vec3(0.); // для бранча emissive-mask (не тестировал на нём)

в ray.rgen:

color /= pdf / 10;

изображение
изображение
изображение
изображение

Но это без текстур! Сейчас попробую добиться чтобы текстуры восстановить.

@0x4E69676874466F78
Copy link
Collaborator

Возвращаю base_color в исходное состояние и делаю:

    payload.emissive = kusok.emissive * emissive_color;
...
    colour *= 0.25;
    colour = reinhard02(colour, vec3(25.));

изображение
изображение

Это не идеально, как видно стал неправильный скайбокс (убирание pow не сильно улучшает ситуацию), а ещё на уровне неправильная яркость у поинтлайтов.

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 26, 2021

Чтобы сделать с правильной яркостью надо:

		const float hack_attenuation = 1.f;
		const float hack_attenuation_spot = 1.f;

@0x4E69676874466F78
Copy link
Collaborator

#319

@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Dec 26, 2021

Резюмирую, проблема была в TWO_PI вместо PI в pdf. Кроме этого точечные источники света надо делить на 2, там видимо тоже где-то TWO_PI или типа того, надо поискать будет.
После этого тонемаппинг reinhard (обе версии) работают корректно, а вот с aces_tonemap что-то не так.

@0x4E69676874466F78

This comment has been minimized.

@w23 w23 added this to HLRT Feb 8, 2023
@w23 w23 added the materials label Apr 28, 2023
@0x4E69676874466F78 0x4E69676874466F78 moved this to 🆕 New in HLRT Jun 4, 2023
@0x4E69676874466F78
Copy link
Collaborator

0x4E69676874466F78 commented Nov 2, 2023

Всё здесь довольно сильно устарело.
Проблемы с эмиссив текстурами в общем плане решены, нет только масок и выпуска освещения из цветов текстуры, для этого уже есть #277. Нужны ли прямо маски отдельный вопрос, т.к. это эмулируется через эмиссив текстуры.
Закрываю.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working materials ray tracing visual bug Visual glitches, something looks incorrectly
Projects
Status: Done
Status: Done
Development

No branches or pull requests

2 participants