тени трафарета - движок Doom 3 - ошибки точности - трещины в тенях - почему?

8

Я тестирую ограничения движка Doom 3 - в отношении максимального размера карты.

Я заметил некоторые ошибки точности тени трафарета, которые становятся более выраженными, когда объекты удаляются все дальше и дальше от начала карты.

в положении: -10901 -18214 -11204 example1

в положении: -10802 -26483 -19383 example2

в положении: -10802 -34683 -27540 example3

Я полагаю, что эти ошибки были названы «теневыми трещинами», но я не уверен, как эти артефакты назывались ранее.

Почти все артефакты появляются вдоль границ света / тени - что можно увидеть здесь: введите описание изображения здесь

Кто-нибудь видел этот тип графического артефакта раньше с трафаретными тенями? Как они называются? В чем причина?

Больше примеров: MISC1 MISC2

Это ванильный движок Doom 3, который можно найти здесь: https://github.com/TTimo/doom3.gpl

Я заметил, что во время тестирования cvar r_useOptimizedShadows (который обрабатывает теневые объемы геометрии появления мира), артефакт исчез. Затем я работал над этой функцией:

R_LinkLightSurf( &vLight->globalShadows, tri, NULL, light, NULL, vLight->scissorRect, true /* FIXME? */ );

который я изменил на это:

R_LinkLightSurf( &vLight->globalShadows, tri, NULL, light, NULL, vLight->scissorRect, false /* FIXME? */ );

Это избавляет от артефактов - но теперь предполагается, что мы никогда не находимся в теневых объемах геометрии появления мира. Поэтому всякий раз, когда мы заходим в теневой объем, этот теневой объем не отображается должным образом.

Stepan1010
источник
1
Не уверен насчет этой конкретной реализации, но с плавающей точкой теряет точность, чем дальше вы идете от нуля.
concept3d
2
Согласовано. 7 цифр - это почти максимальная точность, которую вы можете ожидать от 32-битных чисел с плавающей запятой (иначе C / C ++ float). Вы легко израсходовали 5 из них. en.wikipedia.org/wiki/…
snake5
@ concept3d - я полагаю, что преобразование соответствующих чисел с плавающей запятой поможет? Если у кого-то есть технические ноу-хау, чтобы сделать это. Даже если это приведет к увеличению времени рендеринга.
Stepan1010
1
@glampert Я обновил вопрос. Это ванильный двигатель Doom 3.
Stepan1010
1
Что происходит, когда вы меняете вычисления теневого объема? (Например, просто масштабируйте все теневые объемы на небольшое значение). Артефакты все еще появляются / изменяются / исчезают?
Рой Т.

Ответы:

3

Я наконец-то нашел решение - на самом деле несколько разных решений. Я не выяснить действительную причину артефакта от графического программирования точки зрения - но я нашел несколько решений.

Как я уже говорил в своем вопросе, оказалось, что артефакт возникает только на предварительно вычисленных теневых объемах статической геометрии появления мира (которая в основном представляет собой геометрию, которая, как знает двигатель, никогда не будет двигаться, поэтому он предварительно рассчитывает заранее время теневых томов и прочего с помощью команды, введенной в консоль, называемой «dmap»). Я не понял, почему это было только в тени статической геометрии появления мира, а не на любой из моделей ASE или LWO.

Теперь, что я заметил, было то, что на самом деле существует множество параметров, которые можно использовать с командой dmap - один из этих параметров называется «shadowOpt» - который должен обозначать уровень оптимизации теней. Этот параметр устанавливает перечисление - кажется, есть несколько различных уровней оптимизации теней:

typedef enum {
    SO_NONE,            // 0 // NOTE: I haven't tried this one yet - should test this one.
    SO_MERGE_SURFACES,  // 1 // NOTE: this was the original default one - it causes some artifacts - the ones I have been trying to fix.
    SO_CULL_OCCLUDED,   // 2 // NOTE: this one works the best - takes a bit longer - but it has alot of unnecessary print statements that could probably be removed.
    SO_CLIP_OCCLUDERS,  // 3 // NOTE: I haven't tried this one yet - but it is not used anywhere.
    SO_CLIP_SILS,       // 4 // NOTE: I haven't tried this one yet - should test this one.
    SO_SIL_OPTIMIZE     // 5 // NOTE: this one doesn't seem to work well at all - and it takes an extrememly long amount of time - was probably an expirimental version.
} shadowOptLevel_t;

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

Одним из мест, который дал мне некоторые подсказки, был комментарий здесь в tr_stencilshadow.cpp:

// if we are running from dmap, perform the (very) expensive shadow optimizations
// to remove internal sil edges and optimize the caps
if ( callOptimizer ) {

Теперь проблема только с выполнением этой «дополнительной» оптимизации теней во время «dmap» состоит в том, что, если какой-либо из этих источников света будет когда-либо перемещен (что всегда возможно в зависимости от типа проекта, который вы делаете), то он по умолчанию вернется к «неоптимизированный» процесс создания теневого объема в реальном времени (для перемещенного источника света) и артефакты появятся для этого источника света. Поэтому единственный способ гарантировать, что эти артефакты не появятся, - это всегда запускать очень дорогой процесс оптимизации для этих статических теней появления в мире. Это на самом деле очень дорого, так что это было бы абсолютным последним средством, если вы не можете найти правильное графическое решение. (если вы это сделаете, не забудьте опубликовать свое решение здесь.)

Я бы порекомендовал всем, кто создает большие карты для ванильного движка Doom 3 - и использует геометрию появления мира - они создают cvar, который они могут изменять в зависимости от своих потребностей в создании оптимизированных теневых объемов в реальном времени. Я назвал мой cvar r_useExорогоShadowOptimizations - который, кажется, оксюморон. Например:

// if we are running from dmap, perform the (very) expensive shadow optimizations
// to remove internal sil edges and optimize the caps
if ( callOptimizer || r_useExpensiveShadowOptimizations.GetBool() ) {

Я также рекомендую, чтобы в зависимости от того, насколько велики ваши карты (и при условии, что источники света не будут двигаться), вы должны повысить уровень оптимизации статического теневого объема с помощью параметра "shadowOpt" для dmap.

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

Stepan1010
источник
2

Это вполне может быть ошибка точности плавающего указателя, поскольку Doom использует floats для рендеринга (в основном это ограничение OpenGL). Однако, возясь tr_stencilshadow.cpp, я заметил этот комментарий, который может быть связан с проблемой (внутри PointsOrdered()функции):

// vectors that wind up getting an equal hash value will
// potentially cause a misorder, which can show as a couple
// crack pixels in a shadow

....

// in the very rare case that these might be equal, all that would
// happen is an oportunity for a tiny rasterization shadow crack

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

glampert
источник
1
Я также видел этот комментарий. Однако, когда я закомментировал код этой функции и просто вернул ей значение true (или false - это не имеет значения) - это, похоже, вообще не имеет никакого визуального значения. Как вы думаете, кто-нибудь из разработчиков ответит, если я отправлю им письмо? Я чувствую, что они, вероятно, не ответят. Я думаю, я мог бы попробовать это, если все остальное не удается.
Stepan1010
@ Stepan1010 Ну, не знаю, Кармак классный парень, я однажды отправил ему письмо по поводу чего-то, не связанного с программированием, и он ответил. Полагаю, это не повредит попыткам ... Но, возможно, вам следует отправить письмо сопровождающему, поскольку Carmack больше не является членом idSoftware. Если вы показываете законную проблему и работу, которую вы сделали, они могут быть заинтересованы.
Гламперт