В том-то и дело, что там в коде идёт сравнение с результатом дотпродукта, а не с прямой записью констант. Даже при условии, что мы действуем в 2д пространстве это откровенно стрёмный кейс. Я вообще удивился как оно работало. Потом вспомнил - у меня же компилятор на даблах. Переключил на флоаты - действительно ошибок стало кратно меньше. Ну это не дело.
Там главное даже камент есть, что неплохо бы заюзать хэширование.
Добавлено 10-05-2020 в 22:26:
Полностью заткнул все ошибки и предупреждения. Что для этого потребовалось сделать?
1. переключиться в режим одинарной точности (перекомпилить)
2. поскольку оптимизация происходит в 2D и использует построение ортогонального базиса - надо непременно юзать ту функцию, которую использовали в D3. MakeNormalVectors. Они все "типа правильные", но код потом намертво привязывается к конкретной реализации и глючит с другой.
3. мало этого - в MakeNormalVectors пришлось еще и заюзать табличный InvSqrt. И вот только тогда все ошибки исчезли. Ну что можно сказать? Зашибись! Отличный оптимизатор.
Добавлено 10-05-2020 в 22:31:
В D3 вообще много такой табличной математики для флоатов. Неудивительно что они не боялись их сравнивать напрямую кое-где.
Добавлено 10-05-2020 в 23:36:
На домашнем компе сепульчер сразу стартанул под 650 фпс
напомню что предидущий рекорд был 420. И это еще на толком не отстроенной системе, я чёрт знает что там рисуется сейчас. Виз-то старый.
Добавлено 10-05-2020 в 23:41:
Вон он, весь сепульчер в кадре. ~350 тысяч полигонов. Я ж говорил, что это должно быть быстро.
Тут выяснился один недостаток нового подхода, я думаю вы уже догадались в чём он заключается. В ку3 детайлы не карвились по границам дерева, они просто добавлялись в карту в любом случае. И были видны из какого-то лифа. Здесь же идёт строгое обрезание по секущей плоскости ноды. Иногда (не часто), маппер намеренно располагает детайл ЗА ограничивающим брашем (ну например этот браш невидимый). В ку3 этот детайл бы добавился в уровень в любом случае, а здесь получается, так что невидимая геометрия BSP попросту отрезает его, сама карта при этом, естественно собирается без утечек, но визуально на месте этих патчей-моделей остаются дыры, причём, поскольку мапперы еще и любят их точно совмещать, их отрезание сильно зависит например от режима точности. В одинарном режиме отсекает практически всё, в двойном - ну кое-что.
Т.е. добавление просто считает, что детайл попал в солидную ноду.
Взять вот карту Сока для примера, Focal Point. У него там солидные структуры по бокам лестниц и прямо на них же положены планарные детальные ромбовидные патчи. Патчи там очевидно потому, что брашы такие формы проблематично текстурировать, в радианте не было таких инструментов вроде. И вот оно лежит точно на ноде и отсекается.
Надо подумать как лучше разрешать подобные ситуации.
Добавлено 13-05-2020 в 14:26:
Принял такое решение: если детальный полигон лежит точно на секущей плоскости ноды - делаем его копию и пускаем обе копии дальше вниз по дереву. Одна копия наверняка попадёт в солидный лиф и будет уничтожена, вторая попадёт в валидную арию. Но даже если каким-то чудом в видимый лист попадут обе копии - лишнюю уничтожит оптимизатор.
Но детайлы не должны уничтожаться никоим образом. И уж тем более не должны зависеть от точности эпсилона.
// put front face in front node, and back face in back node.
6
if( DotProduct( fnormal, normal ) > NORMAL_EPSILON ) // usually near 1.0 or -1.0
7
*front = in;
8
else *back = in;
9
}
10
else
11
{
12
vec_t sum = 0.0;
13
for( i = 0; i < in->numpoints; i++)
14
{
15
dot = DotProduct( in->p[i], normal );
16
dot -= dist;
17
sum += dot;
18
}
19
20
if( sum > NORMAL_EPSILON )
21
*front = in;
22
else *back = in;
23
}
24
return;
25
}
Китайская логика. То есть оно как бы лежит точно на плоскости, но при этом мы всё равно пытаемся найти на какую сторону её поместить.
Это вот и есть тот самый корень всех бед и выпадающих полигонов. Т.е. это по большей части определять бесполезно. У нас определение намертво завязывается на точность вещественного, это обязательно сглючит. Чуть-чуть подвигаешь полигоны - сглючит в другом месте.
Это просто ошибка в логике. ChopWindingInPlace к примеру не уничтожает виндинг, лежащий на плоскости независимо от того, находится ли он чуть-чуть за или чуть-чуть перед ней. Ну просто потому что мы в этом случае вступаем на очень зыбкую почву, когда наши предположения целиком завязаны на точность вещественных. Такой код не будет нормально работать уже.
Добавлено 13-05-2020 в 14:49:
Вот скрины
Там где на первом скриншоте дырка - на самом деле большой нулл-браш от пола и до потолка, типа колонны (вы можете скачать исходник этой карты у Сока на сайте и сами посмотреть). Верхняя и нижная часть идут под углом градусов в 8, поэтому не отсекаются. Средняя часть, видимая на втором скриншоте - никакой не браш, это планарный патч, который тут заюзали. скорее всего чтобы легче было текстурировать. А коллизия обеспечивается вот как раз этим невидимым брашем. Плюс наверное эти патчи еще и в мета-сурфсы превратили, я уже не помню. Ну вот. И получается, что этот невидимый браш создаёт плоскость у ноды. И патч ложится точно на него. И естественно отсекается, как попавший в солид-арию за плоскостью ноды. Чего, естественно быть не должно.
Добавлено 13-05-2020 в 15:00:
ЗЫ. У Кармака в D3 более изящное решение - проверить куда смотрит нормаль секущей и сравнить с текущим виндингом. И уже в зависимости от этого положить спереди или сзади. Здесь в чём плюс - мы уже не завязаны на точность. Смотрим только на знак дотпродукта.
Добавлено 13-05-2020 в 15:13:
Это вот тот самый случай, про который я и говорю - если задача в принципе не решается в одном измерении\подходе, ну значит надо поменять сам подход.
C++ Source Code:
1
vec_t sum = 0.0;
2
for( i = 0; i < in->numpoints; i++)
3
{
4
dot = DotProduct( in->p[i], normal );
5
dot -= dist;
Вот этот у нас пытается для каждого вертекса исходного виндинга определить максимальный отступ от плоскости. Но это же бессмысленно! Нам уже WindingOnPlaneSide дал чёткий ответ, что полигон лежит точно на плоскости. Дальше мы на граничной точности вещественных пытаемся что-то определить. Иногда получается хорошо, иногда не очень. Это не может быть надёжным. Просто представьте на секунду, что dot во всех случаях вернул 0.0. И что тогда? А с нормалью - это не математика, это чисто логическое допущение, что если уж плоскость и полигон смотрят в одну сторону, то и полигон следет расположить перед секущей. И это допущение прекрасно работает (ну впрочем я еще потестирую, на коллоизационных брашах, у меня там с ними как раз были такие проблемы).
Добавлено 13-05-2020 в 15:42:
Вся Edge Of Forever в камере. Неплохо для дохлой GT640? Раньше я вообще боялся на нее взглянуть отсюда.
Так, ну чтожы. Похоже я нашёл идеальный подход для создания каких угодно уровней. Который не устареет в будущем, у которого виз не будет считать часами, на базе которого можно реализовать те самые миллионы полигонов в кадре без особых тормозов. И при всём при этом - он по прежнему привычен для классического маппинга брашами. Но позволит делать весь уровень моделями или там террайнами.
Так что теперь основная задача: финализация формата уровней.
Потом можно будет заняться освещением.
Дядя Миша писал: Так, ну чтожы. Похоже я нашёл идеальный подход для создания каких угодно уровней. Который не устареет в будущем, у которого виз не будет считать часами, на базе которого можно реализовать те самые миллионы полигонов в кадре без особых тормозов. И при всём при этом - он по прежнему привычен для классического маппинга брашами. Но позволит делать весь уровень моделями или там террайнами.
Не имеющий аналогов в мире? д.Миша прости, но я не мог удержаться .
Цитата:
Дядя Миша писал: Вся Edge Of Forever в камере. Неплохо для дохлой GT640? Раньше я вообще боялся на нее взглянуть отсюда.
Это я так понимаю с освещением скомпилено?
А как все это будет выглядеть на открытых пространствах? Или при мельтешении в кадре куче всяких зомбей, например? Или если графония добавить?
Не просядет ли в итоге фпс и не захлебнется все это дело?
Я ж написал откуда была взята основная идея - Doom3.
Цитата:
Cep}I{ писал: Это я так понимаю с освещением скомпилено?
Нет, освещения еще нет.
Цитата:
Cep}I{ писал: А как все это будет выглядеть на открытых пространствах? Или при мельтешении в кадре куче всяких зомбей, например? Или если графония добавить?
Не просядет ли в итоге фпс и не захлебнется все это дело?
Основная идея в том, чтобы сам формат не выступал ограничителем скорости, чтобы он сам не тормозил отрисовку. Чтобы производительность зависела от мощности видеокарты, а не каких-то устаревших ограничений.
В этой области сложно придумать что-то новое или оригинальное, но у меня было дополнительное условие, как вы помните - чтобы народ мог кубать под новым ксашем по прежнему. А кто не хочет кубать - пусть делает весь уровень одной моделькой, как в метро или сталкере. Или ландшафтом.
То есть идея в том, чтобы формат органично переваривал разные подходы к левел-дизайну. И естественно всё будет проверяться на практике, как на тяжёлых моделях, так и на тяжёлых брашевых уровнях. Можно будет взять какую-нибудь сцену из уе или юнити и тоже попробовать. Ну это потом.
Слева оптимизированная сетка, справа неоптимизированная.
Я специально выбрал такой ракус, потому что во первых эта оптимизация влияет на вертексные цвета, во вторых в ней по идее есть смысл только при использовании полного иссечения всех треугольников по дереву, а не просто расталкивание их по границам арий. Правда в чём смысл этого полного иссечения, я честно говоря так и не понял. Сначала всё разрежем, потом склеим обратно, кое-где рёбра свапнутся. А самая мякотка в том, что без оптимизации этой - фпс даже немного выше
Может в самом D3 это для теневых объемов как-то использовалось, не знаю.
Впрочем есть еще вариант без полного иссечения по дереву, но с оптимизацией. Надо будет еще его опробовать
Мне кажется, или с обведённым ребром что-то не то?
У меня пара вопросов по вот этой конкретной карте в связи с тем, что у меня в ксене похожие юзкейсы будут.
1.Смешивание текстур на полу, песок пререходит в гравий. Насколько я помню, в оригинале симонок там расставлял какие-то браши со спецтекстурой на першинах полигонов. Если у меня такая нора сделана моделью, то возможно-ли этот переход прямо на ней нарисовать, например через цвета вершин?
2. Вот когда такая сложная геометрия, то замощение модели текстурами без швов и растяжений становится нетрививальной задачей. Есть ли готовый способ, что бы как-то автоматизировать это наложение в шойдере, так что бы в целом замостить поверхность лоскутами максимального размера, в местах совемещения разных лоскутов с разными осями зайдействовать какое ни будь смешивание?
thambs писал: расставлял какие-то браши со спецтекстурой на першинах полигонов.
Он сперва пытался дотпродуктом альфу нагенерить, но потом дополнительно этих брашей натолкал в вертексы. Главное народ не ленивый.
Цитата:
thambs писал: Если у меня такая нора сделана моделью, то возможно-ли этот переход прямо на ней нарисовать, например через цвета вершин?
Я помню эту модель. Думаю вполне. Там много всяких вариантов.
Цитата:
thambs писал: так что бы в целом замостить поверхность лоскутами максимального размера, в местах совемещения разных лоскутов с разными осями зайдействовать какое ни будь смешивание?
Там несколько вариантов автогенерации текстурных координат, да.
Дядя Миша, а сработает ли такой вариант: в коде кастомного рендера XashXT сделать копию бсп дерева конкретно для отрисовки, а потом его оптимизировать тем подходом какой ты использовал, еще когда только начинал работу над рендерером в XashNT? Ведь поскольку код рендерера целиком можно менять, то вроде бы как не обязательно придерживаться именно бинарной совместимости, и можно немножко доугой вариант дерева впихнуть, с которым оптимизации будут работать. Возможно ли такое реализовать, или же все таки есть какие-то фундаментальные различия, которыми нельзя пренебречь?
Сработать-то оно сработает, но особой пользы не принесёт. Точнее принесёт её меньше чем могло бы. Потому что это же дерево крайне желательно использовать не только для отрисовки, но и для проверки видимости на сервере. Там дикие тормоза просто из-за целой кучи этих накопленных лифов, оно идёт по хеадноде, дерево большое. Т.е. надо и на сервере тоже такое дерево. Ну можно наверное заморочиться, но я этим заниматься точно не буду. Могу код дать, но вас жы в больничку увезут с воспалением мозга.
Дядя Миша писал: Сработать-то оно сработает, но особой пользы не принесёт. Точнее принесёт её меньше чем могло бы. Потому что это же дерево крайне желательно использовать не только для отрисовки, но и для проверки видимости на сервере. Там дикие тормоза просто из-за целой кучи этих накопленных лифов, оно идёт по хеадноде, дерево большое. Т.е. надо и на сервере тоже такое дерево. Ну можно наверное заморочиться, но я этим заниматься точно не буду. Могу код дать, но вас жы в больничку увезут с воспалением мозга.
Как я понимаю, со стороны сервера это отразится оверхедом на CPU? Это конечно не оптимально, как оно могло бы быть, но всё же меньшее из зол. Ну во всяком случае я бы попробовал новое дерево прикрутить, будет хорошо если поделишься кодом.