ПрограммированиеФорумГрафика

Объёмный свет / объёмный туман (решено)

Страницы: 1 2 37 8 Следующая »
#0
22:16, 30 дек 2023

Задача - сделать объёмный свет, т.е. подсветку пространства вокруг источника света.

Пример (HL Alyx):

HL Alyx Volumetrics 1 | Объёмный свет / объёмный туман (решено)

HL Alyx Volumetrics 2 | Объёмный свет / объёмный туман (решено)

Само собой, рисовать здоровенные спрайты размером с половину экрана не вариант, филлрейта не хватит, еще и со смешиванием. Поскольку крупных источников света в кадре обычно немного, напрашивается решение во время отрисовки сцены вести луч к камере и измерять расстояние до каждого источника. Такое решение описано здесь: https://ijdykeman.github.io/graphics/simple_fog_shader

Работает прекрасно, мобильный процессор справляется с тремя-четырьмя источниками (обычно в кадре больше и нет, при повороте камеры можно аккуратно тушить ушедшие из поля зрения источники и зажигать новые). Но хочется иметь возможность придать освещенной части фигуру, отличную от круга, чтобы делать вот такие штуки:

HL Alyx Volumetrics 4 | Объёмный свет / объёмный туман (решено)

HL Alyx Volumetrics 5 | Объёмный свет / объёмный туман (решено)

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

Пока придумал следующее: в отдельном фреймбуфере, разрешением в несколько раз меньше основного, рисуем любую геометрию с размытыми краями. Затем при отрисовке сцены накладываем готовую текстуру с объёмным светом. Попробовал, работает, причём мобильный процессор справился даже с несколькими десятками спрайтов размером с половину экрана (в реальности во много раз меньше экрана, фреймбуфер-то маленький). Ступенек пикселей не видно, поскольку все края размытые.

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

Пока идея такая:
- 2-3 круглых источника делать первым способом;
- "фигурный свет" рисовать вторым способом, не допуская перекрытия (не более 1 источника в кадре), в один из каналов вписывать глубину для проверки на этапе смешивания;
- для источников, находящихся сильно далеко, просто рисовать маленький спрайт прямо на сцене.

Что думаете? Может, есть еще какая-нибудь известная техника? Или какой-ниибудь определенный термин, по которому погуглить решения?

Отмечу, что ищу дешёвые в плане производительности решения, всякие там реймарчинги не предлагать. Спасибо.

#1
22:59, 30 дек 2023

Скорее всего свет в пост процессинге делают.

+ Показать
#2
23:02, 30 дек 2023

Угадал :)
https://otosection.com/volumetric-light-scattering-as-a-post-processing-effect/

#3
23:09, 30 дек 2023

Ещё пример с множеством перекрывающихся объёмов:

Cyberpunk 2077 Volumetrics 1 | Объёмный свет / объёмный туман (решено)

ronniko
Вопрос не в том, как это реализовано конкретно здесь, а в том, как это подешевле сделать и без постпроцессинга.

> https://otosection.com/volumetric-light-scattering-as-a-post-processing-effect/
Статью нейросеть что ли сгенерирована? Бессвязный набор слов.

#4
23:11, 30 дек 2023

romanshuvalov
> Но в этом случае никак нельзя учесть глубину
Может быть, надо рисовать всю геометрию, а не только свет.

#5
23:14, 30 дек 2023

iw4nna.rock
> Может быть, надо рисовать всю геометрию, а не только свет.
Нельзя: рендер идёт в фреймбуфер низкого разрешения, при отсечении по depth test я получу гребёнку из пикселей.

#6
23:19, 30 дек 2023

romanshuvalov
> при отсечении по depth test я получу гребёнку из пикселей
не понятно, что вы имели в виду.
Гребёнку наверно можно убрать размытием. Один фиг на ваших скринах всё в жутком блуме...

#7
23:28, 30 дек 2023

iw4nna.rock
> Гребёнку наверно можно убрать размытием.
Размытие нельзя, прямой рендер на экран, постпроцессинга нет.

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

#8
0:00, 31 дек 2023

romanshuvalov
> Вместо очертания камня при таком способе будет лесенка из пикселей низкого
> разрешения
А, понятно.
Ну мне такое делать не приходилось, но если пришлось бы, то мне захотелось бы наверно нарисовать "объёмную" картинку с точками света, которые знают о своей глубине, можно маленькую, сильно размыть её, вычислить глубины в межточечном пространстве, можно даже на ЦПУ, а потом сверху добавить геометрию из камней, столбов, стен итп.

#9
0:28, 31 дек 2023

iw4nna.rock
> а потом сверху добавить геометрию из камней, столбов, стен итп.
Так часть геометрии позади, часть впереди. А источников несколько, и геометрия может быть между ними.

#10
1:23, 31 дек 2023

Интересная тематика. Как такой вариант? Восстанавливаем depth из depth буфера, знаем параметры источника, считаем длину освещенной части (суммарную плотность частиц по лучу от камеры до мирового положения пикселя в волюме), умножаем на свойства частицы.

Суммарную плотность считаем либо какой-то формулой, либо шагами по лучу в интервале от ближней части волюма источника до мирового положения пикселя.

#11
4:48, 31 дек 2023

romanshuvalov
Что думаете? Может, есть еще какая-нибудь известная техника? Или какой-ниибудь определенный термин, по которому погуглить решения?

Блюм на объектах с эмиссией на мобильных картах не работает? Или вас не устраивает произодительность?
По-моему на примерах одни и те же подходы, ну плюс волюметрикс ещё. Вы альтернативу ищите?

#12
8:05, 31 дек 2023

romanshuvalov
> Само собой, рисовать здоровенные спрайты размером с половину экрана не вариант

Это почему вдруг? Есть тесты?

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

#13
8:46, 31 дек 2023

Не знаю, насколько применимо в контексте современного графония, но в старых играх была кое-где такая реализация — интеграл по волюметрикам считался отдельным проходом для вертексов, а у фрагментов это значение уже только интерполировалось. Хм, сейчас думаю, а ведь на хай-поли, наоборот, должно работать только лучше. Так что предлагаю реально попробовать сделать так:
—> считай "некрасивые дорогие конусы" как есть, но не во фрагментном шейдере, а в повершинном (заграждения от геометрии на этой стадии можно игнорировать, я думаю),
—> во фрагментном, просто делай добавление/интерполяцию (как там этот фог у тебя работает) от последнего шага формулы для фога.
Что-то типа:

void vertex_shader() {
    your_normal_vertex_shader_shit(...);

    [var_fog_power, var_fog_coverage] = integrate_fog(uni_camera_pos, attr_vertex_pos);
}

void fragment_shader() {
    float3 surface_color = calc_surface_color_like_usual(...);
    final_color = surface_color * (1 - var_fog_coverage) + var_fog_power;
}
#14
10:57, 31 дек 2023

betauser
Это просто более сложная вариация на первый вариант, визуально слабо отличающаяся, но имеющая те же проблемы.

MSA2
> Блюм на объектах с эмиссией на мобильных картах не работает?
Посмотрите на четвертый скриншот, о каком блюме речь?

Der FlugSimulator
> Это почему вдруг? Есть тесты?
Да. Если на Oculus Quest 2 отрисовать сцену, а затем еще раз поверх всего фреймбуфера нарисовать полупрозрачный квад - проиводительность упадёт ниже приемлимого уровня. На ПК-видеокартах такой проблемы нет, но мобильные чипы имеют низкий филлрейт. Поэтому я всё рисую в один проход.

> зачем на телефоне всё это.
Не на телефоне, на VR-устройстве с Qualcomm Snapdragon XR2 и разрешением 1440х1560 в каждый глаз.

Имбирная Ведьмочка
Допустим, мы имеем плоскую стену (один квад) и перед ней висящий фонарь, как на третьем скриншоте. Каким образом расчёт четырёх точек квада поможет нарисовать конус?

Страницы: 1 2 37 8 Следующая »
ПрограммированиеФорумГрафика

Тема в архиве.