Я наконец-то нашел решение - на самом деле несколько разных решений. Я не выяснить действительную причину артефакта от графического программирования точки зрения - но я нашел несколько решений.
Как я уже говорил в своем вопросе, оказалось, что артефакт возникает только на предварительно вычисленных теневых объемах статической геометрии появления мира (которая в основном представляет собой геометрию, которая, как знает двигатель, никогда не будет двигаться, поэтому он предварительно рассчитывает заранее время теневых томов и прочего с помощью команды, введенной в консоль, называемой «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 имеет смысл, поскольку оно решает проблему и занимает всего несколько секунд для компиляции карты.