Спасибо, многое прояснилось! Про альбедо, запекание мультивыборки и антитайлинг всё понятно.
Про мипмапы тоже подумал, что неплохо бы мипмапить только по двум координатам. В моей демке камера свободная, и с пипмапами стало немного хуже, потому выключил.
> это будет либо шум из-за нормали, либо из-за твоего способа окраски, так как он не интерполируется.
Шум однозначно из-за нормали. В "фильтрации" сделан поиск модального (которое чаще всего среди выборок) значения номера травинки, что немного улучшает ситуацию по сравнению с взятием первого попавшегося номера.
Но дело не в этом. Такое окрашивание я вообще добавил в последнюю очередь, а шум (в градациях серого) был и до окрашивания.
Ощущение, что не хватает разрешения текстуры. Например, в одном текселе мы попадаем лучом по геометрии, а в соседнем - нет. При выборке получается фильтрованное значение расстояния, на котором фрагмент не отбрасывается ни глубиной ни дискардом. Нормаль из-за фильтрации тоже получается какой попало. Что с ней делать?
> художники мне дают меш, я его запекаю примерно таким же алгоритмом.
А как запечь (и использовать) меш с непараллельными волокнами?
если используется линейная фильтрация, то глубина должна линейно интерполироваться и нормаль должна тоже линейно интерполироваться вместе с ней. поэтому шума быть не должно, от разрешения текстуры это на зависит (у меня нет шума даже на очень низком разрешении)
Я правильно понимаю, что запечь полноценную 3д-модель (а не фигуры на двумерной плоскости) получилось потому, что камера фиксированная?
VirtualVoid
> Я правильно понимаю, что запечь полноценную 3д-модель (а не фигуры на двумерной
> плоскости) получилось потому, что камера фиксированная?
нет, каждый патч повёрнут случайным углом, поэтому это свойство использовать нельзя. я запекаю 3д-модель в допущении, будто она обозревается с одного(фиксированного) угла и далее шейдере пытаюсь компенсировать возникающие из-за этого артефакты.
Разобрался с контурами, возникают из-за кривого алгоритма трассировки.
Вот пример слоя с торчащими нормалями (красные):
Кодирование нормалей исключил, здесь текстура была во float32 без преобразований. Должно починиться добавлением допуска в правильном месте и множественными лучами на тексель.
Suslik
> и далее шейдере пытаюсь компенсировать возникающие из-за этого артефакты.
Из каких соображений лучше компенсировать?
Я попытался искать коэффициент для растяжения пространственных текстурных координат, зная угол запекания и фактический угол зрения. Потом растягивал на этот коэффициент в направлении зрения. Получилось не очень.
Есть ещё мысль итерационно поискать правильный семпл, делая дополнительные выборки. Но во фрагментном шейдере не очень хочется так делать.
VirtualVoid
я высчитывал дальность пересечения, чтобы видимая часть геометрии, находящейся над землёй, была постоянной вне зависимости от угла. это не совсем та же формула, что и для каста по вертикальным призмам, но идея та же. просто там где-то вместо 1/cos() получается 1/tan() или что-то в этом духе (нет доступа к шейдеру сейчас).
Suslik
Выглядит симпатично, но не очень реалистично. Трава растёт более вертикально (не с таким сильным наклоном), а сам наклон столь сильно не изменяется на такой небольшой площади. Обычно наклон есть в одну сторону - куда преимущественно дует ветер.
Окей, с компенсацией угла при расчёте глубины всё понятно.
Теперь рассмотрим цвет/нормаль. Для простоты пусть рендерится горизонтальная плоскость, выводим цвет, а нормаль пока отбросим. Вот что получается (разрез, вид сбоку):
Смотрим из глаза во фрагмент А горизонтальной плоскости под углом круче, чем угол запекания. AC - направление запекания, AB - направление взгляда. Мы должны были увидеть цвет какого-то куска запечённой геометрии по направлению взгляда, а видим по направлению запекания. Возникает "преломление", зависящее от угла взгляда. При перспективной камере получается, что чем круче угол взгляда, тем больше фрагментов плоскости попадают в один и тот же тексель запечённой текстуры. В итоге, при взгляде в надир получается такое (сингулярность ближе к правому нижнему углу):
Я попробовал несколько способов борьбы с этим эффектом:
- Компенсировать глубину так, что фрагменты под камерой (если таковые попали в кадр), будут прятаться под ландшафт. В результате вместо сингулярности получается дырка с неровными, правильными краями. Её размеры увеличиваются относительно ландшафта при подъёме камеры над ландшафтом.
- Засемплить расстояние, вычислить точку пересечения луча с запечённой геометрией, репроджектнуть из неё на плоскость (пробовал по разному), получить новые текстурные координаты. По этим координатам засемплить цвет/нормаль.
Во всех случаях результат мне не понравился.
Suslik
У тебя вначале видео, которое вначале статьи, этой проблемы не видно. Подскажи как бороться, куда думать?
VirtualVoid
я, имея угол запекания для точки C, модифицирую прочитанное расстоение AC, чтобы оно совпадало с длиной AB для текущего направления взгляда. этот способ даёт точный результат для горизонтальной плоскости, но может выдавать артефакты (менее существенные, чем без него) для более сложных мешей. но самый лучший способ бороться с такими артефактами — разбивать траву на патчи, где трава примята настолько, чтоб никогда не приходилось смотреть вдоль направления запекания. короче, единственно корректного решения я тут не нашёл, но использование нескольких аккуратных трюков, в общем-то, вполне помогает избавиться от таких проблем. они на самом деле всплывают в менее очевидных местах потом, например, при расчёте френеля для environment map'а и выглядят как перезасвеченные участки, потому что отражают больше света, чем должны бы, но это тоже можно скрывать аккуратной настройкой параметров.
Suslik
Но цвет при этом всё равно остаётся взятым из точки C?
Suslik
При такой модификации AC глубина в "стянутых" фрагментах не будет достаточной, чтобы скрыть артефакт под ландшафтом. Скорее наоборот, при взгляде под камеру, расстояние будет корректироваться в меньшую сторону.
> разбивать траву на патчи, где трава примята настолько, чтоб никогда не приходилось смотреть вдоль направления запекания.
Всмысле, чтобы трава была как-бы примята плоскостью?
Вдоль направления запекания артефактов нет вообще. Зачем тогда избегать взгляда вдоль запекания?
VirtualVoid
> Вдоль направления запекания артефактов нет вообще. Зачем тогда избегать взгляда
> вдоль запекания?
имел в виду не вдоль направления запекания, а вертикально (в пространстве запечённой текстуры).
> Скорее наоборот, при взгляде под камеру, расстояние будет корректироваться в меньшую сторону.
у меня нет сейчас доступа шейдерам пое (я дома), но формула была примерно такая:
float cos_ang = dot(normal, ab); length_base = texture3D( ...).r; length_corrected = length_base / cos_baked * cos_ang;
эта формула работает для окологоризонтальных запечённых поверхностей, наблюдаемых под любым углом.
> Но цвет при этом всё равно остаётся взятым из точки C?
да
> При такой модификации AC глубина в "стянутых" фрагментах не будет достаточной
короче, я тестил так: запёк меш с грибами и положил его поверх земли. далее я удостоверился, чтобы грибы торчали из земли всегда на одну и ту же высоту вне зависимости от направления взгляда. это преобразование будет немного сжимать или растягивать грибы в горизонтальной плоскости, но если они торчат из земли на одно и то же расстояние, то по моему опыту это избавляет от основных артефактов и выглядит норм. вообще эти доводки я делал после того, как получил уже более-менее нормально выглядящий результат (после съёмки того видео, например), так как проще эксперминтировать, когда уже есть какая-то опорная точка.
> Всмысле, чтобы трава была как-бы примята плоскостью?
не плоскостью, но да, примята. вообще изменение направления волокон путём использования косоугольного базиса для перевода угла зрения из мировых координат в запечённые — это, пожалуй, основной инструмент, который позволяет избавиться от повторяемости, позволяет делать колыхание на ветру и его нужно правильно разрулить, чтобы под любым базисом все преобразования делались одинаково (правильно).
Suslik
Понял, спасибо за ответы!
Ещё отвлечённый вопрос. На какой геометрии у тебя всё это происходит? В видео (в статье и с exilecon) похоже, что только на плоскости. Делал ли ты это на искривлённом ландшафте с учётом его касательного базиса и прочими вытекающими?
Тема в архиве.