Новости с фронта
Хм... Нет, А зачем? Важно ведь только направление нормали. Я сначала считаю нормали ко всем поверхностям, затем нахожу нормали к вершинам путем суммирования векторов нормалей смежных поверхностей. Затем нормализую вектор нормали и ищу косинус угла между вектором нормали и нормализованным вектором освещения, что и определяет интенсивность освещения (диффузное отражение, для земли составляющая зеркального отражения принебрежима мала). Так же пробовал суммировать нормализованные вектора нормалей (во сказанул), но результат выходит грубее. Затем уже два раза применяется линейная интерполяция, сначала находятся интенсивности освещения на границах тайла в каждой точке (из уравнения прямой), затем уже идет отрисовка линий, где происходит линейная интерполяция интенсивности из уже известных двух крайних значений. Собственно за счет этого видать и происходит засветка границ.sam0delk1n пишет: Результат на количество поверхностей делишь? Это как среднее арифметическое -- надо делить на количество членов.
Тут как раз случай только солнца, другие источника света если и будут то не либо пренебрежимы либо будут обрабатываться уже по канонам 2х мерной графики (маска осветления, что накладывается поверх)sam0delk1n пишет: Кстати пока в игре только direct lighing от солнца, можно интерполировать затенение. А вот если в игре будут точечные источники света, размером сопоставимые с трисами, тогда лучше интерполировать только нормали, а затенение считать для каждого пикселя отдельно, иначе результат совсем неточный будет.
Для оптимизации если поверхность является плоской, т.е. координаты Z всех вершин одинаковы используется другой алгоритм отрисовки (простой блиттинг). Т.е. для них не применяется освещение ни в первом случае ни во втором. Потом или добавлю затемнение в их отрисовку или что более желательно подгоню отрисовку не плоских тайлов, так чтобы не было заметно этих границ. Пока же не возился, так как это черновой вариант и постоянно править код в двух местах сложнее + это помогает пока определять как именно работает освещение по сравнению с исходным тайлом.sam0delk1n пишет: Ну вот на скринах отдельные тайлы выглядят как с флэт-шейдингом. Даже на безтекстуроной поверхности. Как будто соседний тайл не учитывается. Почему так?
Game isn't a dream, it is the reality, reality which is coming while we dream...
Правда надо понимать что это тестовая яркая текстура, выбранная специально для наглядности работы интерполяции. Реальные текстуры обладают меньшей яркостью и как следствие менее чувствительному к эффекту "пятна примата" (надо же дать этому явлению какое-то имя).
Для сравнения скрин этого же места с прошлым вариантом:
Как видно в случае если скосы более чем из одного тайла результат сравним с тем что выше, но в противном случае ошибочная засветка ребер режет глаз и грызет ухо.
Game isn't a dream, it is the reality, reality which is coming while we dream...
- sam0delk1n
- Не в сети
- Интересующийся
-
- Сообщений: 76
- Спасибо получено: 47
Всё верно. Для честного косинуса проводить нормализацию не обязательно. Но косинус можно заменить скалярным умножением (dot product), тогда нужно нормализовать оба вектора, причем вектор света должен быть направлен от поверхности к источнику света, а не по направлению света. В шейдерах обычно делают так:StaticZ пишет: Хм... нет я сначала считаю нормали ко всем поверхностям, затем нахожу нормали к вершинам путем суммирования векторов нормалей смежных поверхностей. Затем нормализую вектор нормали и ищу косинус угла между вектором нормали и нормализованным вектором освещения, что и определяет интенсивность освещения
Для этого и нормализую, тогда косинус будет просто сумой попарного произведения проекций двух векторов. Хотя так как вектор освещения является постоянным и не зависит от положения камеры при оптимизации я могу хранить заранее рассчитанные значения интенсивности света для нужных вершин\граней.sam0delk1n пишет: Всё верно. Для честного косинуса проводить нормализацию не обязательно. Но косинус можно заменить скалярным умножением (dot product), тогда нужно нормализовать оба вектора, причем вектор света должен быть направлен от поверхности к источнику света, а не по направлению света.
Но оптимизация это уже потом, сначала надо добиться хорошего алгоритма сглаживания а тут пока не все так радужно, как хотелось бы.
Game isn't a dream, it is the reality, reality which is coming while we dream...
Как видно при небольших скосах проблема остается, но меньше заметна, при крутых все ровно, правда при этом появляется острое ребро. В теории конечно данный вариант должен бы быть лучше, но на практике не особо, отсрые углы тех же гор режут глаз, а раньше они смотрелись шикарно.
Вообщем пока больше ничего в голову не лезет, артефакты возникают из-за сглаживания, попытка их ликвидации приводит к угловатости и снижению плавности теней. Посему пока больше склоняюсь к варианту изложенному в посте #7227 . В конце концов если избегать использования острых углов (что вообщем-то противоестественно и лишено явного смысла) и ярких текстур (вроде этого белоснежного снега) проблема теряет свою актуальность.
Game isn't a dream, it is the reality, reality which is coming while we dream...
- sam0delk1n
- Не в сети
- Интересующийся
-
- Сообщений: 76
- Спасибо получено: 47
Так или иначе любая линейная интерполяция никогда гладкой не будет. У неё информация только двух значений. А надо больше, чтобы понимать как строить кривую. Можно попробовать кубическую/бикубическую. Но там громоздкие вычисления. Прежде лучше Фонга попробовать тогда уж.
ЗЫ кстати не фонгом и гуро мир един есть и другие и имя им легион к примеру модель Кука-Торренса, Шлика.
Вообще тут проблема не столько в интерполяции сколько в расчете нормалей, это наглядно демонстрирует проблему
Game isn't a dream, it is the reality, reality which is coming while we dream...
- sam0delk1n
- Не в сети
- Интересующийся
-
- Сообщений: 76
- Спасибо получено: 47
Кстати эти алгоритмы было бы неплохо реализовать в виде dll (лучше бинарной) чтобы ей могли пользоваться и другие люди (например я). Актуально для систем где нет поддержки d3d и opengl (например kolibrios).
Да тут как раз проблема в малой полигональности, что в частных случаях и порождает эти проблемы. Думаю для решения этой проблемы надо не лезть в дебри с всякими Фонгами, а отталкиваться от конкретных целей и задач. В данном случае точностью освещения можно пренебречь, главное это равномерность интерполяции.sam0delk1n пишет: Вообще и современные игры используют линейную. Но там достаточно полигонов, между ними очень небольшое изменение нормали.
Это конечно так, только у нас всетаки случай 2х мерной игры и это излишне. У меня сейчас и так ФПС просело в 20 раз, правда там дико не оптимизированный код с расчетом кучей нормалей всего и вся вокруг тайла в том числе и лишних и прочая рабочая муть... Конечно потом подчищу, но вообщем тут надо быть аккуратнее с дополнительными расчетами.sam0delk1n пишет: А текстуры, бамп/параллакс добавляют дополнительный шум и маскируют недостатки затенения поверхности.
Не понял.sam0delk1n пишет: Нужно искать баланс между количеством полигонов и сложностью затенения. Возможно cpu с его медленной памятью будет лучше переваривать полигоны чем масштабные затенения по площади.
Позже подробнее опишу как что реализовал и как считал. Там собственно увидите, что я не совсем честно рисую 3D а сильно мухлюю используя особенности графики конкретного движка. Так что для общего случая расчета и отрисовки 3D боюсь мой код без переделывания попросту не подойдет. Собственно этим и объясняется отсутствие свободных или коммерческих истинных 2х мерных движков, так как там везде идет оптимизация под конкретные особенности, что определяется особенностями графики и геймплея. Можно сделать конечно 2д движок общего назначения но он будет крайне маломощным и подойдет лишь для самых простых проектов (вроде тех же jRPG эпохи NES или RPGMaker (кстати насчет последней версии не знаю, а с прошлыми поковырявшись в дизасме (когда делал exshell) могу сказать, что там вообще не замарачивались - вся отрисовка через WinAPI, причем каким-то дико извращенным способом, они зачем-то бьют изображение на строки шириной насколько помню в 8 пикселей и блиттинг идет построчно, накой это скок не думал так и не смог понять, возможно оно как-то связанно с архитектурой PSP)).sam0delk1n пишет: Кстати эти алгоритмы было бы неплохо реализовать в виде dll (лучше бинарной) чтобы ей могли пользоваться и другие люди (например я). Актуально для систем где нет поддержки d3d и opengl (например kolibrios).
а тем временем еще один вариант:
вообщем-то чем-то лучше чем-то хуже - диагональные склоны стали лучше, а вот вертикальные наоборот ужасны. для сравнения старый алгоритм на них давал почти идеальное затемнение -
PS Кстати можете просветите мамонта по поводу того что изменилось в 3х мерной графике последнего поколения? Если раньше 3D сцена резала глаз мало полигональностью, размытыми текстурами за счет их малого разрешения, но при этом радовала ровными четкими линиями при любых разрешениях, то теперь от малейшего поворота камеры линии мерцают, лишь новомодные алгоритмы сглаживания вроде FXAA, MSAA, CSAA позволяют хоть как-то избавиться от этого явления.
Game isn't a dream, it is the reality, reality which is coming while we dream...
- sam0delk1n
- Не в сети
- Интересующийся
-
- Сообщений: 76
- Спасибо получено: 47
Основная причина -- большое количество деталей сцены размером меньше пиксела, распространение спекуляра и расширенного диапазона освещения (который hdr). Вот пример: есть участок поверхности с бликами и тёмными частями, например поверхность воды, которая далеко от камеры. В размер пиксела входит несколько участков с бликами и тёмных, но пиксел может быть только одного цвета, и по честному нужно взять усреднённых цвет всего попадающего в пиксел изображения, но реально просто берётся та часть которая приходится на центр пиксела. И если камера движется, туда будет попадать то блик то тёмная часть и пиксел будет мерцать туда-сюда. А сильный спекуляр и hdr только усиливают этот эффект. На самом деле проблема для текстур возникла давно, ещё в 90х и решение было найдено в виде mip-mapping'а и фильтрации текстур. Например mip-mapping нужен чтобы подогнать разрешение текстуры под разрешение участка экрана, куда она выводится. А анизотропный фильтр помогает делать выборку текстур для поверхностей под острым углом к камере -- вдоль проекции делается выборка довольно большого количества текселей и усредняется их результат. Для обычных диффузных текстур этого было достаточно. Но затем появился спекуляр-бамп мэппинг с очень детальным рельефом, всякие мелкие детали геометрии, например листья, тонкие провода и т.п. Поэтому стали использовать мультивыборку. Например SSAA или MSAA (не путать с SMAA) -- первый это фактически рендеринг всего изображения в более высокое разрешение, а затем уменьшение его до разрешений экрана с усреднением цвета соседних пикселей, таким образом те детали которые раньше были меньше пикселя, теперь становятся больше чем субпиксели и более корректно усредняются при переходе к экранному разрешению. А второе (MSAA) -- там сначала детектируются области экрана содержащие грани геометрии (их силуэты) и мультивыборка происходит только в этих местах, а не по всему изображению. Это обычно сильно быстрее, но будут обрабатываться только лесенки геометрии (antialiasing), а например бликующие поверхности или листва (которая рисуется альфа-блендингом) -- нет. Для альфа-блендинга обычно делают свои алгоритмы сглаживания, отдельные. Но в последнее время также используют морфологическое сглаживание (FXAA, SMAA, MLAA, Temporal SMAA и т.п. -- разновидностей много). Их особенность в том что они обрабатывают уже отрендеренное 2д изображение. А значит их можно добавить к любой игре, не влезая в её внутренности. Обычно даже в настройках драйвера можно включить, а сама игра может и не поддерживать его. Короче удобная встраиваемая штука. Но недостаток в том что субпиксели ей недоступны, а значит обработка деталей меньше пикселей лучше не станет. Взамен такое сглаживание просто чуть-чуть замыливает изображение чтобы яркий пиксель не сильно выделялся на фоне остальных. Но всё-равно например наблюдается известный эффект "разрыва проводов". Для проводов и других тонких вещей иногда даже отдельный шейдер делают. Морфологические алгоритмы как правило очень быстрые. Короче у каждого алгоритма сглаживания есть свои преимущества и недостатки. Поэтому их комбинируют. Например в GTA5 используется MSAA и FXAA вместе, первый хорошо помогает в отрисовки мелкой листвы, травы, а второй хорошо справляется с силуэтами, отражениями. Temporal SMAA помогает улучшать плавность движения объектов. То есть когда объект переходит из одного пиксела в следующий, то следующий не сразу принимает цвет объекта, а постепенно, по мере того как объект преодолевает расстояние между пикселами. Например это повышает реалистичность колыхания мелкой листвы. Ну SSAA это решение в лоб, оно лучше всего сглаживает, но например считай что качество 2x провалит fps в два раза, 4x -- в четыре и т. д. Однако же например в Tomb Rider 2013, Metro 2033 (Last Light) Redux только такие режимы сглаживания и есть. Так или иначе все режимы сглаживания сейчас пишутся вручную на шейдерах, потому что те что в стандартном T&L более не совместимы с deferred shading'ом, который повсеместно сейчас в любой игре.StaticZ пишет: PS Кстати можете просветите мамонта по поводу того что изменилось в 3х мерной графике последнего поколения? Если раньше 3D сцена резала глаз мало полигональностью, размытыми текстурами за счет их малого разрешения, но при этом радовала ровными четкими линиями при любых разрешениях, то теперь от малейшего поворота камеры линии мерцают, лишь новомодные алгоритмы сглаживания вроде FXAA, MSAA, CSAA позволяют хоть как-то избавиться от этого явления.
Ну вот на видеокартах быстрая память (в 10 раз быстрее в среднем) и доступ к ней тоже значительно быстрее. На cpu много уровней: системная память, потом кеш L3, L2, L1 и обычно там несколько сотен тактов процессора надо, чтобы первые байты дошли из памяти в регистры процессора. За это время уже можно десять раз матрицы перемножить.StaticZ пишет: Не понял.
Таким образом видеокарте очень легко нарисовать один большой треугольник на весь экран и быстро его заполнить цветом. А вот используя системную память сам факт заполнения больших участков буфера цветом уже проблематичен. Поэтому раз заполняется всёравно медленно, можно за это время посчитать полигоны и воспользоваться этой возможностью чтобы рисовать плавные рельефы. Одним словом увеличение количества полигонов, если они рисуются на ту же площадь изображения, не сильно замедлят рендеринг, как это было бы в случае с видеокартой.


