forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Проекты C++ (http://forum.boolean.name/forumdisplay.php?f=56)
-   -   raycasting (http://forum.boolean.name/showthread.php?t=18551)

Samodelkin 14.10.2013 00:45

Ответ: raycasting
 
Цитата:

Да у меня тоже самое. Пока добавил костыль
Убрал костыль, исправил ошибку, добавил механизм исключений в каждый поток, так что теперь надежность ядра рендера выше.

Переписал все вычисления на float (раньше были целочисленные, как и следует wolf3d подобным играм). Тем самым образом исчезли артефакты связанные с неточной выборкой текстур и расчетом геометрией на близком расстоянии (тем более что разрешение выше чем в wolf3d и целочисленные косяки стали более заметны).

Убрал предрасчетные тригонометрические таблицы (опять же по причине достаточной производительности), кое где в критических местах работает кеширование.

Добавил функцию расчета тумана. Вообще она универсальная, и можно делать не только туман, а вообще любой эффект, у которого есть линейная зависимость от расстояния (например в демке я сделал погружение дальних объектов в темноту).

Добавил AABB и сделал небольшую механику на них. Теперь все объекты коллиzятся через AABB (раньше был примитивный рассчет на окружностях). Например у перса появилась инерция, а при соударении со стенами (перса =)) гасится импульс только вдоль нормали к стене. Таким образом позже будет легко добавить отскоки и прыжки. Также AABB можно тестировать на пересечение с отрезками и лучами, что тоже будет полезно. Тестирование пересечений есть двух типов: первое просто проверяет на пересечение двух AABB, второе перемещает AABB по всей тестируемой траектории движения с заданным шагом. Тем самым быстрые мелкие объекты не будут проскакивать через другие мелкие объекты. Хорошей оптимизации для обсчета всех AABB наподобие деревьев пока нет, но я сделал предварительный расчет расстояния, если оно больше чем может преодолеть объект то тестирование прерывается. Вобщем у меня на карте около 1000 AABB, обсчитывается на одном ядре и никакого падения производительности незаметно.

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

Кстати к вопросу почему я не использую готовые физические движки. Я думаю попробовать сделать оригинальную механику из какой-нибудь игры вроде doom или quake. Вообще у меня есть написаный ранее модуль для другого движка с physx, но вот пока я думаю он не нужен...

Да самое заметное это то, что появился пол и потолок. Незнаю точно как делали в doom 1, но я уже делал нечто среднее между кастингом и трейсингом, потому как пол и потолок обрабатываются попиксельно (что то наподобие как делают в пиксельных шейдерах, только конечно с меньшим количеством кода).

Сейчас используется nearest фильтр при выборке из текстуры и он создает очень "шумное" изображение. Я пробовал делать билинейную фильтрацию, но она скорей нужна в случае когда текстура с низким разрешением растягивается на экран большого разрешения, а в случае с этим проектом нужно как раз наоборот. Анизотропные фильтры уже не потянет софтварный рендер, поэтому я решил пока оставить так, и может быть потом сделаю сглаживание всего изображения как пост-процесс эффект и этого будет достаточно.

Кстати разрешение я снизил до 640х320, но поднял fps до 60 (ну может у кого и меньше будет). Добавил пару пост-процесс эффектов. В сумме с низким разрешением изображение получилось в таком трешевом киберпанковском стиле =). Но в целом оптимизировать еще есть куда, я думаю раза в 3-4 можно ускорить - simd и лучшее распределение по потокам. Раз это рейкастинг, то сложность сцены почти не повлияет на произоводительность, так что на загруженных сценах сильно медленней не должно быть.

И теперь проект также работает на Linux.

maze_6_4.rar (Windows)
maze_6_5.tar.7z (Linux)

Arton 14.10.2013 02:29

Ответ: raycasting
 
Ёпт!
Так и должно быть???



Фтопку такую постобработку!

mr.DIMAS 14.10.2013 16:52

Ответ: raycasting
 
Круто! Походив 5 минут по лабиринту не вылезло ни единого бага, что круто. В качестве постэффекта лучше сделать легкий шум, чем кадровую развертку. Работает всё шустро. Среднее фпс - 55. А текущее иногда проваливается до 47.

Samodelkin 15.10.2013 00:30

Ответ: raycasting
 
Цитата:

Ёпт!
Так и должно быть???
2Arton Может тебе просто графика в старых играх вообще не нравится?

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

Попробуй тогда в демке ниже сам понастраивать разные комбо постэффектов.

maze_6_6.rar (Windows)
maze_6_7.tar.7z (Linux)

Добавил несколько пост эффектов и возможность их включать/выключать (можно комбинировать).
Сейчас я не занимался их оптимизацией, поэтому данная версия довольно медленная.
Управление:
1 - вкл/выкл эффект xray (хаотичные белые точки, не путать с шумом).
2 - вкл/выкл эффект кадровой развертки (его нужно видеть в движении, от скринов толку мало).
3 - переключение функции тумана (ничего|темнота|туман).
4 - вкл/выкл затенение по углам.
5 - вкл/выкл шум.
6 - переключение цветовых фильтров (обычный|черно-белый|сепия).
7 - вкл/выкл билинейную фильтрацию (она вообще какая то плохая, видимо я накосячил где-то в ее логике - не так хорошо семплы смешивает, потом перепроверю).
8 - поставить ограничение в 30fps.
9 - поставить ограничение в 60fps.
0 - неограниченный fps.

Ну конечно настроек у каждого эффекта больше, но клавиш не хватит - потом вынесу все в cfg файл.

Arton 15.10.2013 18:09

Ответ: raycasting
 
Цитата:

Сообщение от Samodelkin (Сообщение 268792)
2Arton Может тебе просто графика в старых играх вообще не нравится?

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

Попробуй тогда в демке ниже сам понастраивать разные комбо постэффектов.

maze_6_6.rar (Windows)
maze_6_7.tar.7z (Linux)

Добавил несколько пост эффектов и возможность их включать/выключать (можно комбинировать).
Сейчас я не занимался их оптимизацией, поэтому данная версия довольно медленная.
Управление:
1 - вкл/выкл эффект xray (хаотичные белые точки, не путать с шумом).
2 - вкл/выкл эффект кадровой развертки (его нужно видеть в движении, от скринов толку мало).
3 - переключение функции тумана (ничего|темнота|туман).
4 - вкл/выкл затенение по углам.
5 - вкл/выкл шум.
6 - переключение цветовых фильтров (обычный|черно-белый|сепия).
7 - вкл/выкл билинейную фильтрацию (она вообще какая то плохая, видимо я накосячил где-то в ее логике - не так хорошо семплы смешивает, потом перепроверю).
8 - поставить ограничение в 30fps.
9 - поставить ограничение в 60fps.
0 - неограниченный fps.

Ну конечно настроек у каждого эффекта больше, но клавиш не хватит - потом вынесу все в cfg файл.

Причём тут нравится не нравится. Эффект развёртки всё портит! ИМХО

FPS выше 19 не поднимается :(

ЦП хороший - AMD FX-6100, 3,3 ГГц

Последний пример хорошо смотрится, вариант по умолчанию понравился, молодец, продолжай в том же духе :super:

P. S. Обзор мышью будешь делать??

Samodelkin 15.10.2013 18:51

Ответ: raycasting
 
Цитата:

Сообщение от Arton
FPS выше 19 не поднимается

Цитата:

Сообщение от Samodelkin
Сейчас я не занимался их оптимизацией, поэтому данная версия довольно медленная.

Как раз сейчас буду оптимизировать.
Цитата:

Сообщение от Arton
P. S. Обзор мышью будешь делать??

А что она у тебя не работает?

Движение по вертикали чуть позже добавлю - там не все так просто - возможности рейкастинга пока не дают камеру вверх/вниз поварачивать.

Arton 15.10.2013 21:31

Ответ: raycasting
 
Цитата:

Сообщение от Samodelkin (Сообщение 268819)
А что она у тебя не работает?

Движение по вертикали чуть позже добавлю - там не все так просто - возможности рейкастинга пока не дают камеру вверх/вниз поварачивать.

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

Samodelkin 21.10.2013 01:54

Ответ: raycasting
 

:winlogo: maze_6_9.rar
:luxlogo: maze_6_10.tar.7z


Сделал несколько экспериментов с фреймбуферами. Изначально был фреймбуфер, который хранил пикселы формата A8R8G8B8, но записывал их столбцами, а не строками, так как я предположил что это будет лучше, потому что рейкастинг именно так рисует пикселы. Однако на стадии рейкастинга особого прироста это не давало, а вот для постпроцесс эффектов это было неудобно - когда надо было копировать группу пикселей, memcpy это делает быстрей чем копирование по одному в цикле. И я сделал построковый фреймбуфер, а тот старый удалил вообще. Также, в постпроцесс эффектах довольно часто приходится конвертировать из A8R8G8B8 в R32fG32fB32f формат, и чтобы сэкономить на этих операциях с добавил такой формат фреймбуфера, и такой же сделал для текстур. Однако в данном случае увеличивается их размер и в среднем получается что они работают примерно с одинаковой скоростью, так что я оставил оба варианта на всякий случай.


Исправил несколько багов с BMP загрузчиком. Я не внимательно читал вики, а там было сказано что расположение строк пикселей в BMP находится в обратном порядке, что я не учел, и все изображения раньше приходилось в рендере еще раз переворачивать.


Добавил новые эффекты: "RGB расслоение", раздельное горизонтальное и вертикальное размытие по Гауссу с выборкой из 5 соседних пикселей, на основе размытия сделал эффект расфокусировки линзы объектива по краям экрана (как в игре Limbo). Большинство эффектов распараллелены. Оптимизация проводилась за счет кеширования и предварительного расчета маски актуальных пикселей, другими словами заранее определялись пикселы которые нужно изменить и только они и меняются, избегая обращения к другим пикселям (RAM позволяет все это делать без каких либо пинг-понгов на квадах, как это было на шейдерах). Однако еще есть много места для оптимизации. В общем с учетом добавления новых (довольно тяжелых) эффектов fps удалось поднять до 30 (i7 930, на Linux). Однако, не хотелось бы никого обижать :), но на Windows MinGW примерно тот же код, с теме же ключами, компилируется на 30-40% более медленным! Особенно проблемы доставляет mingw-реализация некоторых стандартных функций. Так что по возможности буду их убирать из кода и обходиться своими.

Цитата:

Управление:
1 - вкл/выкл эффект xray (хаотичные белые точки, не путать с шумом).
2 - вкл/выкл эффект кадровой развертки (его нужно видеть в движении, от скринов толку мало).
3 - переключение функции тумана (ничего|темнота|туман).
4 - вкл/выкл затенение по углам.
5 - вкл/выкл шум.
6 - переключение цветовых фильтров (обычный|черно-белый|сепия).
7 - вкл/выкл билинейную фильтрацию (она вообще какая то плохая, видимо я накосячил где-то в ее логике - не так хорошо семплы смешивает, потом перепроверю).
8 - поставить ограничение в 30fps.
9 - поставить ограничение в 60fps.
0 - неограниченный fps.
Теперь на цифре 6 к тем что уже были добавлен эффект "RGB расслоение", а + и - можно задавать силу эффекта, который в данный момент выбран цифрой 6.
Размытие по краям линзы включено все время.

mr.DIMAS 21.10.2013 09:07

Ответ: raycasting
 
Все работает. Багов не замечено. Возможно ли при рейкастинге сделать мипфильтрацию? А то аж рябит в глазах от выборки пикселей.

ФПС при одном эффекте мыла по краям - среднее 27
ФПС при всех включенных эффектах - 22 ( тоже среднее ).

Samodelkin 21.10.2013 23:03

Ответ: raycasting
 
Цитата:

Сообщение от mr.DIMAS
Возможно ли при рейкастинге сделать мипфильтрацию? А то аж рябит в глазах от выборки пикселей.

На самом деле проблема случайных пикселей (ряби текстур) должна решаться комплексным подходом с помощью MIP-mapping и анизотропной фильтрации. Один только mipmapping не решает проблему с текстурами на поверхностях, которые находятся под острым углом к вектору направления обзора. Потому что на большом расстоянии разрешение подходящей mip текстуры поперек вектора обзора будет на много выше чем вдоль вектора обзора и невозможно будет подобрать оптимальную mip текстуру. Здесь нужна анизотропная фильтрация, которая сначала подбирает нужную mip текстуру поперек вектора направления обзора, а затем делает несколько выборок вдоль и усредняет результат. Но именно анизотропная фильтрация очень требовательна к пропускной способности памяти, что может сильно перегружать RAM, и так загруженную работой с фрейбуферами.

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

Третий вариант - это просто сделать правильные текстуры, в которых впринципе не будет такого большого контраста текселей. Или например сделать специальную mip фильтрацию (на стадии загрузки или даже сохранения текстуры в редакторе), которая в каждой следующей уменьшеной копии текстуры убирает сильно выделяющиеся по контрасту текселы, в таком случае можно обойтись mip-mapping'ом с обычным nearest (или bilinear) фильтром.

Samodelkin 27.10.2013 01:52

Ответ: raycasting
 
maze_6_11.rar

Тестировал оба формата (A8R8G8B8 и R32fG32fB32f) на скорость - они показывают практически одинаковые результаты, разница в районе 2-3%, что совсем несущественно. Так как float формат занимает в 3 раза больше места, то он менее перспективен и я его удалил (это касается фреймбуферов, текстур и буферов эффектов). Так что теперь рендер будет работать только с A8R8G8B8.

Попробовал разные способы автооптимизацию (автовекторизацию, выбор целевой архитектуры, настройку математики и прочие опции компилятора), в среднем удалось ускорить в 2,5 раза, это поверх опции -O3 (я на gcc собираю), что весьма неплохо... Но там еще есть над чем поработать, так что в следующий раз подробности расскажу =). Также оптимизировал локальность размещения данных в памяти, чтобы было меньше кеш промахов, но тут имхо для лучшего результата нужно свой аллокатор делать.

За счет небольшой прибавки скорости, я восстановил качество некоторых пост эффектов, которое раньше было урезано.

Исправил баг в коде билинейного фильтра. Теперь понятно почему он раньше так плохо выглядел. Сейчас все сглаживается как и положено - можно в упор подойти к стене и понажимать 7 (включение/выключение билинейной фильтрации).

Частично реализовал систему mipmaping'а. Значит я написал класс-контейнер который содержит внутри себя классы текстур, каждая текстура имеет свой размер, соответственно mipmap уровню. Генерация уровней происходит после загрузки текстуры, в качестве фильтра для генерации уменьшенных копий используется усреднение значений 4 соседних текселей (ну вобщем ничего особенного). Во время выборки уровень определяется на основе расстояние (то есть для рейкастинга у нас известна длина луча, никаких z-buffer'ов тут нет). Однако на данный момент я сделал линейную зависимость, что неправильно - дальние текстуры будут быстро понижаться в уровне. Нужен более сложный алгоритм, который кроме расстояния, будет учитывать разрешение текстуры, угол обзора FOV, а также угол наклона поверхности к вектору обзора. Скорей всего все это я попробую учесть в реализации анизотропной фильтрации.

То что касается этой демки: 7 - включить/выключить билинейный фильтр, 8 - включить/выключить mipmapping, 3 - как и раньше перключение темноты/тумана/без_тумана - если его отключить то будет видно далеко и как меняются mipmap уровни в линейной зависимости от расстояния.

mr.DIMAS 27.10.2013 21:45

Ответ: raycasting
 
Среднее ФПС со стандартным набором эффектов - 44.
Со всеми включёнными - 42.
Графон стал лучше. С мипами не так сильно рябит. Но без тумана текстура вообще исчезает вдали - будто мип 1х1.
Работает шустро.

Samodelkin 27.10.2013 22:02

Ответ: raycasting
 
maze_6_12.rar


Цитата:

Но без тумана текстура вообще исчезает вдали - будто мип 1х1.
Поправил.
Вывел более менее оптимальную формулу расчета мип-уровней:
Код:

twoTanAlpha = 2.0f * tan( fieldOfViewInRad / 2.0f );
fbRealWidth = rayLen * twoTanAlpha * factor;
pixSize = fbRealWidth / scrWidth;
texSize = objWidth / texWidth;
lv = ceil( sqrt( pixSize / texSize ) ) - 1.0f;
// rayLen - длина луча.
// scrWidth - ширина экрана в пикселях.
// objWidth - ширина объекта с текстурой (в мировых единицах измерения).
// texWidth - ширина текстуры в текселях.
// fieldOfView - угол обзора в радианах.

Однако всеравно приходится выбирать баланс с помощью коэффициента factor между текстурами которые ложаться на сурфейсы параллельные плоскости экрана и текстурами которые ложаться на сурфейсы под большим углом к плоскости экрана. Другими словами либо видна размытость стен, либо рябь на земле и потолке.

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

mr.DIMAS 28.10.2013 00:01

Ответ: raycasting
 
Стало намного лучше.

SIMD будешь использовать?

Samodelkin 28.10.2013 01:29

Ответ: raycasting
 
Сейчас я уже с ключом sse компилирую, только толку от него пока мало - нужно правильные циклы писать чтобы автовекторизатор срабатывал. Так что да нужно вручную ассемблировать. Сначала буду матлибу переписывать c simd, а потом рендер. Если я правильно понимаю то в 64 битном режиме доступно 16 xmm регистров, что значительно должно повысить производительность. Но этим я и ограничусь, avx не буду делать, да и железки у меня такой нет. Потом буду смотреть в сторону gpgpu.


Часовой пояс GMT +4, время: 08:58.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
Перевод: zCarot