Класически карти на сенки накратко. Четвърти блог за разработчици: Нови графични функции на Combat Arms

Светлината има три основни характеристики: яркост (Multiplier), цвят (Color) и сенки, хвърляни от обектите, които осветява (Shadows).

Когато подреждате източници на светлина в сцена, не забравяйте да обърнете внимание на техния цвят. Източниците на дневна светлина имат син нюанс, но за да създадете изкуствен източник на светлина, трябва да му придадете жълтеникав цвят.

Трябва също така да се има предвид, че цветът на източника, симулиращ улично осветление, зависи от времето на деня. Следователно, ако сюжетът на сцената включва вечерно време, осветлението може да бъде в червеникавите нюанси на летния залез.

Различни програми за изобразяване предлагат свои собствени алгоритми за генериране на сенки. Сянката, хвърлена от даден обект, може да каже много - колко високо е той над земята, каква е структурата на повърхността, върху която пада сянката, какъв източник е осветил обекта и т.н.

В допълнение, сянката може да подчертае контраста между предния и фоновия план, както и да „издаде“ обект, който не е в зрителното поле на обектива на виртуалната камера.

В зависимост от формата на сянката, хвърлена от обекта, сцената може да изглежда реалистична (фиг. 6.6) или не съвсем правдоподобна (фиг. 6.7).

Както казахме по-горе, истинският лъч светлина претърпява голям брой отражения и пречупвания, така че истинските сенки винаги имат размазани ръбове. В 3D графиката се използва специален термин за описание на такива сенки - меки сенки.

Постигането на меки сенки е доста трудно. Много програми за изобразяване решават проблема с меките сенки, като добавят неточков източник на светлина, който има правоъгълна или друга форма към интерфейса на 3ds max 7. Такъв източник излъчва светлина не от една точка, а от всяка точка на повърхността. Освен това, колкото по-голяма е площта на източника на светлина, толкова по-меки са сенките при изобразяване.

Има различни подходи за визуализиране на сенките: използване на карта на сенките (Shadow Map), проследяване (Raytraced) и глобално осветление (Global Illumination). Нека ги разгледаме по ред.

Ориз. 6.6. Обект с меки сенки

Ориз. 6.7. Обект с груби сенки

Ориз. 6.8. Разгръщане на настройките на Shadow Map Params за източник на светлина

Използването на карта на сенките ви позволява да получите размазани сенки

с размити ръбове. Основната настройка на картата на сенките е размерът на картата на сенките (параметър за размер) в разгръщането на настройките на параметрите на картата на сенките (фиг. 6.8). Ако размерът на картата бъде намален, яснотата на получените сенки също ще намалее.

Методът за проследяване позволява да се получат идеално оформени сенки, които обаче изглеждат неестествени поради острите си очертания. Проследяването се отнася до проследяване на пътищата на отделни светлинни лъчи от източник на светлина до обектив на камера, като се вземе предвид тяхното отражение от обекти в сцената и пречупване в прозрачна среда. Методът на проследяване често се използва за изобразяване на сцени, които съдържат огледални отражения.

Започвайки с 3ds max 5, методът Area Shadows се използва за получаване на меки сенки, който се основава на леко модифициран метод за проследяване. Area Shadows (Разпределение на сенките) ви позволява да изчислявате сенките от обект, сякаш няма един източник на светлина в сцената, а група от точкови източници на светлина, равномерно разпределени в определена област.

Въпреки че проследяването на лъчи точно възпроизвежда фините детайли на генерираните сенки, то не е идеалното решение за изобразяване поради острите очертания на получените сенки.

Методът на глобалното осветяване (Radiosity) ви позволява да постигнете меки сенки в крайното изображение. Този метод е алтернатива на проследяването на осветлението. Ако методът за проследяване визуализира само онези области от сцената, които са осветени от светлинни лъчи, тогава методът за глобално осветление изчислява разсейването на светлината в неосветени или сенчести области на сцената въз основа на анализ на всеки пиксел в изображението. Това взема предвид всички отражения на светлинните лъчи в сцената.

Глобалното осветление ви позволява да получите реалистично изображение, но процесът на изобразяване натоварва много работната станция и отнема много време. Ето защо в някои случаи има смисъл да се използва осветителна система, която симулира ефекта на дифузна светлина. В този случай източниците на светлина трябва да бъдат разположени по такъв начин, че тяхното положение да съвпада с местата на пряко излагане на светлина. Такива източници не трябва да създават сенки и трябва да имат ниска яркост. Този метод със сигурност не създава толкова реалистично изображение, каквото може да се получи с помощта на истински метод за глобално осветяване. Въпреки това, в сцени, които имат проста геометрия, това може да бъде доста полезно.

Има няколко алгоритъма за изчисляване на глобалното осветление; един от методите за изчисляване на отразената светлина е проследяването на фотони (Photon Mapping). Този метод включва изчисляване на глобалното осветление въз основа на създаването на така наречената фотонна карта. Фотонната карта представлява информация за осветеността на сцената, събрана чрез проследяване.

Предимството на метода за проследяване на фотони е, че веднъж запазени като фотонна карта, резултатите от проследяването на фотони могат по-късно да се използват за създаване на глобални осветителни ефекти в 3D анимационни сцени. Качеството на глобалното осветление, изчислено чрез проследяване на фотони, зависи от броя на фотоните, както и от дълбочината на проследяване. Използвайки проследяване на фотони, можете също да изчислите ефекта каустик (прочетете повече за ефекта каустик в раздела „Обща информация за визуализацията в 3D графики“, Глава 7).

Сред стандартните източници на светлина, три източника (а именно Spot, Direct и Omni) ни позволяват да изберем типа сенки, които да бъдат изчислени. Ако използваме стандартния Default Scanline Renderer (DSR), тогава следното ще представлява интерес за нас: Advanced ray-traced сенки, Area shadows, Ray-traced сенки, Shadow maps.

Когато изберете тип сянка сред превъртанията на параметрите на IS, се появява превъртане на параметрите на сянка, чието име започва с името на типа.

Карта на сенките

Най-простият и неизискващ тип сенки по отношение на изчислителните ресурси.

  1. Размерът на картата, въз основа на който се изчислява сянката. Колкото по-голяма е картата, толкова по-добро е качеството на изчислената сянка. По-добре е да използвате числа от порядък 2 n
  2. Замъгляване на ръба на сянката. Увеличаването на параметъра ви позволява да се отървете от назъбения ръб, когато резолюцията на картата е ниска
  3. Параметър, отговорен за контролиране на стойността на Bias. Деактивирано по подразбиране (най-добър резултат в повечето случаи). В случай на анимация, активиране на опцията
  4. Ако е деактивирано, светлината преминава през повърхността, ако удари полигони с нормали, обърнати настрани от нея. Активирането на тази опция ви позволява да получите правилни сенки

На фиг. 1 горният ред изображения ясно показва промяната в качеството на сенките с увеличаване на параметъра Size. Дори значително увеличаване на размера на картата не решава проблема с назъбените ръбове на сянката, въпреки че моделът на сянката със сигурност става по-детайлен.

Във втория ред и в трите случая размерът на картата остава същият, но параметърът Sample Range се променя. Чрез постепенното му увеличаване се отървахме от назъбеността, замъглявайки ръба на сянката.

Фиг.1 Промяна на качеството на сянката от типа Shadow Map с различни параметри

Проследени от лъчи сенки

Този тип сянка се изчислява въз основа на алгоритъм за проследяване. Те имат ясни ръбове и е практически невъзможно да се персонализират.

Ray-Traced Shadow е по-точен в сравнение с Shadow Map. Освен това той е в състояние да вземе предвид прозрачността на обекта, но в същото време е „сух“ и ясен, което в повечето случаи не изглежда много естествено. Ray-Traced Shadow е по-взискателен към компютърните ресурси от Shadow Map.

  1. Разстояние на обекта от хвърляната сянка
  2. Дълбочината на трасиране е параметър, отговорен за развитието на сянката. Увеличаването на тази стойност може значително да увеличи времето за изобразяване

Рендирането на Ray-Traced Shadows с Omni тип IC ще отнеме повече време, отколкото комбинация от Ray-Traced Shadows + Spot (или Directional)

Фиг.2 Проследени с лъч сенки от непрозрачни и прозрачни обекти

Усъвършенствани сенки с проследяване на лъчи

Сенките от този тип са много подобни на Ray-Traced Shadows, но както подсказва името, те имат по-разширени настройки, които позволяват по-естествени и правилни изчисления.

  1. Метод за генериране на сянка
    просто – единичен лъч излиза от IC. Сянката не поддържа настройки за изглаждане или качество
    Антиалиас с 1 преминаване – симулира се излъчването на сноп лъчи. Освен това, същият брой лъчи се отразява от всяка осветена повърхност (броят на лъчите се регулира от Качеството на сенките).
    Антиалиас с 2 преминавания – Подобни, но се излъчват два снопа лъчи.
  2. Ако е изключено, тогава светлината преминава през повърхността, ако удари полигони с нормали, обърнати настрани от нея. Активирането на тази опция ви позволява да получите правилни сенки
  3. Брой лъчи, излъчвани от осветена повърхност
  4. Броят на вторичните лъчи, излъчвани от осветената повърхност
  5. Радиусът (в пиксели) на замъгляването на ръба на сянката. Увеличаването на параметъра подобрява качеството на размазването. Ако малките детайли се загубят при замъгляване на ръба, коригирайте това, като увеличите целостта на сенките
  6. Разстояние на обекта от хвърляната сянка
  7. Параметър, който контролира произволността на лъчите. Първоначално лъчите са насочени по строга решетка, което може да причини неприятни артефакти. Въвеждането на хаос ще направи сянката по-естествена
    Препоръчителните стойности са 0,5-1,0. Но по-размазаните сенки ще изискват по-голямо количество трептене

Областни сенки

Този тип сянка ви позволява да вземете предвид размерите на източника на светлина, така че можете да получите естествени разширени сенки, които се „разделят“ и размазват, докато се отдалечавате от обекта. 3dsMax произвежда тези сенки чрез смесване на няколко „проби“ от сенки. Колкото повече „проби“ и колкото по-добро е смесването, толкова по-добра е изчислената сянка.

  1. Формата на въображаем източник на светлина, която ви позволява да определите естеството на сянката.
    просто – единичен лъч излиза от IC. Сянката не поддържа настройки за изглаждане или качество.
    Правоъгълна светлина t – симулира се излъчването на светлина от правоъгълна област.
    Дискова светлина – IC се държи така, сякаш е придобил формата на диск.
    Кутия Light – имитация на кубична ИС.
    Сферична светлина t – имитация на сферична ИС.
  2. Ако е деактивирано, светлината преминава през повърхността, ако удари полигони с нормали, обърнати настрани от нея. Активирането на тази опция ви позволява да получите правилни сенки.
  3. Контролира броя на излъчваните лъчи (нелинейно). Колкото по-високо е числото, толкова повече лъчи, толкова по-високо е качеството на сянката.
  4. Параметър, отговорен за качеството на сянката. За рационално изчисление винаги задавайте числото, по-високо от Shadow Integrity.
  5. Радиусът (в пиксели) на замъгляването на ръба на сянката. Увеличаването на параметъра подобрява качеството на размазването. Ако малките детайли се загубят при замъгляване на ръба, коригирайте това, като увеличите целостта на сенките.
  6. Разстоянието на обекта от хвърлената сянка.
  7. Параметър, който контролира произволността на лъчите. Първоначално лъчите са насочени по строга решетка, което може да причини неприятни артефакти. Въвеждането на хаос ще направи сянката по-естествена.
  8. Размери на въображаемия източник. Length - дължина, Width - ширина, Height (активно само за Box Light и Sphere Light) - височина.

Нека да разгледаме фиг.3. На първия фрагмент. Няколко "проби" на сенки се наслагват една върху друга без никакво преливане. Във втория фрагмент те вече са смесени (количеството на трептене е променено от 0.0 на 6.0). Смесените „мостри“ се възприемат като по-естествена сянка, но качеството му оставя много да се желае. Третият фрагмент показва сянка с отлично качество (Целостта на сянката и Качеството на сянката са променени от единични стойности съответно на 8 и 10).

Втори ред на фиг. 3. илюстрира как се променя характерът на сянката, ако увеличим размера на въображаемия източник. В този случай имаме въображаем източник от типа Rectangle Light (плосък правоъгълен). С увеличаването на зоната на източника се увеличава и размазването на сенките.

Фиг.3 Промяна на качеството на сянката тип Area Shadow с различни параметри

Някои стойности на параметрите са препоръчителни по природа, но всичко е ограничено само от вашето въображение. Най-добрият начин да го разберете е чрез експериментиране. Не се страхувайте да експериментирате със светлината. Уловете настроението на бъдещата картина и се поддайте на настройките.

На фиг.4. шахматен рицар с материал, базиран на проста процедурна текстура на дърво. Три източника на светлина, тонирани в различни цветове. Проста настройка, но въпреки това фигурата изглежда добре.

Фиг.4 Шахматна фигура „Рицар”. Предметна визуализация

Резюме

Осветлението е един от най-важните етапи в работата върху триизмерна сцена. На пръв поглед може да изглежда, че сухата информация от урока не може да се приложи към творческата работа. Въпреки това, с подходяща изобретателност и упорит труд, можете да постигнете невероятни резултати. В края на краищата, всички цифрови изображения са просто колекции от единици и нули, а 3dsMax е просто още един инструмент за вас, точно като молив или четка.

Оригиналният алгоритъм за картографиране на сенки е изобретен доста отдавна. Принципът му на действие е следният:
  1. Начертаваме сцената в текстура (карта на сенките) от позицията на източника на светлина. Тук е важно да се отбележи, че нещата се случват малко по-различно за различните видове източници на светлина.
    Източниците на насочена светлина (до известна степен това включва и слънчевата светлина) нямат позиция в пространството, но за да се образува карта на сенките, тази позиция трябва да бъде избрана. Обикновено тя е свързана с позицията на наблюдателя, така че картата на сенките включва обекти, разположени директно в зрителното поле на наблюдателя. Изобразяването използва ортографска проекция.
    Проекционните източници на светлина (лампи с непрозрачни абажури, прожектори) имат определено положение в пространството и ограничават разпространението на светлината в определени посоки. При рендиране на картата на сенките в този случай се използва конвенционална проекционна матрица на перспектива.
    Всепосочните източници на светлина (лампа с нажежаема жичка например), въпреки че имат определено място в пространството, разпределят светлината във всички посоки. За да конструирате правилно сенки от такъв източник на светлина, трябва да използвате кубични карти, което обикновено означава начертаване на сцената в карта на сенките 6 пъти. Не всяка игра може да си позволи динамични сенки от този вид източници на светлина и не всяка игра има нужда от това. Ако се интересувате как работи този подход, има тема по тази тема.
    Освен това има подклас алгоритми за картографиране на сенки (LiSPSM, TSM, PSM и др.), които използват нестандартни матрици за проекция на изглед, за да подобрят качеството на сенките и да премахнат недостатъците на оригиналния подход.
    Без значение как се формира картата на сенките, тя неизменно съдържа разстоянието от източника на светлина до най-близката видима (от позицията на източника на светлина) точка или функция на това разстояние в по-сложните версии на алгоритъма.
  2. Рисуваме сцената от основната камера. За да разберете дали точка от даден обект е в сянка, достатъчно е да преведете координатите на тази точка в пространството на картата на сенките и да направите сравнение. Пространството на картата на сенките се определя от матрицата изглед-проекция, която е използвана за генериране на тази карта. Чрез транслиране на координатите на обектната точка в това пространство и трансформиране на координатите от диапазона [-1;-1] V , получаваме текстурни координати. Ако получените координати са извън диапазона , тогава тази точка не е включена в картата на сенките и може да се счита за незасенчена. Като направим селекция от картата на сенките, използвайки получените координати на текстурата, ще получим разстоянието между източника на светлина и най-близката точка на всеки обект до него. Ако сравним това разстояние с разстоянието между текущата точка и източника на светлина, точката се появява в сянка, ако стойността в картата на сенките е по-малка. Това е доста просто от логическа гледна точка, ако стойността от картата на сенките е по-малка, това означава, че в тази точка има някакъв обект, който е по-близо до източника на светлина, а ние сме в неговата сянка.
Картографирането на сенки е може би най-разпространеният алгоритъм за изобразяване на динамични сенки днес. Изпълнението на една или друга модификация на алгоритъма може да се намери в почти всеки графичен двигател. Основното предимство на този алгоритъм е, че осигурява бързо образуване на сенки от произволно геометрично сложни обекти. В същото време съществуването на широка гама от вариации на алгоритъма до голяма степен се дължи на неговите недостатъци, които могат да доведат до много неприятни графични артефакти. Проблемите, специфични за PPSM, и начините за преодоляването им ще бъдат обсъдени по-долу.

Картографиране на сенки с паралелно разделяне

Помислете за следния проблем: необходимо е да се рисуват динамични сенки от обекти, разположени на значително разстояние от играча, без да се компрометират сенките от близко разположени обекти. Да се ​​ограничим до насочената слънчева светлина.
Този вид проблем може да бъде особено важен при игри на открито, където в някои ситуации играчът може да види пейзажа на стотици метри пред себе си. В същото време, колкото по-далеч искаме да видим сянката, толкова повече място трябва да попадне в картата на сенките. За да поддържаме правилната разделителна способност на обектите в картата на сенките, ние сме принудени да увеличим разделителната способност на самата карта, което първо води до намаляване на производителността, след което се сблъскваме с ограничение на максималния размер на целта за изобразяване. В резултат на това, балансирайки между производителност и качество на сенките, ще получим сенки с ясно видим ефект на псевдоним, който е слабо маскиран дори от замъгляване. Ясно е, че такова решение не може да ни удовлетвори.
За да разрешим този проблем, можем да измислим проекционна матрица, така че обектите, разположени близо до играча, да получават по-голяма площ в картата на сенките, отколкото обектите, които са разположени далеч. Това е основната идея на алгоритъма Perspective Shadow Mapping (PSM) и редица други алгоритми. Основното предимство на този подход е фактът, че практически не сме променили процеса на изобразяване на сцената, а само методът за изчисляване на матрицата изглед-проекция се е променил. Този подход може лесно да бъде интегриран в съществуваща игра или двигател, без да са необходими големи модификации на последния. Основният недостатък на този вид подход са граничните условия. Нека си представим ситуация, в която рисуваме сенки от Слънцето при залез. Когато Слънцето се доближи до хоризонта, обектите в картата на сенките започват да се припокриват значително. В този случай нетипичната проекционна матрица може да влоши ситуацията. С други думи, алгоритмите от клас PSM работят добре в определени ситуации, например, когато играта рисува сенки от „неподвижното слънце“ близо до зенита.
Фундаментално различен подход е предложен в алгоритъма PSSM. Този алгоритъм може да е известен на някои като Cascaded Shadow Mapping (CSM). Формално това са различни алгоритми, дори бих казал, че PSSM е частен случай на CSM. Този алгоритъм предлага разделяне на пирамидата на видимост (frustum) на основната камера на сегменти. При PSSM - с граници, успоредни на близките и далечните сечни равнини, при CSM - видът на разделението не е строго регламентиран. За всеки сегмент ( разделянев терминологията на алгоритъма) се изгражда собствена карта на сенките. Пример за разделяне е показан на фигурата по-долу.


На фигурата можете да видите разделянето на пирамидата на видимост на 3 сегмента. Всеки от сегментите е подчертан с ограничаващ правоъгълник (в триизмерното пространство ще има паралелепипед, ограничаваща кутия). За всяка от тези ограничени части от пространството ще бъде изградена собствена карта на сенките. Внимателният читател ще забележи, че тук използвах аксиално подравнени ограничаващи паралелепипеди. Можете също да използвате неподравнени; това ще добави допълнителна сложност към алгоритъма за изрязване на обекта и донякъде ще промени начина, по който се генерира матрицата на изгледа от позицията на източника на светлина. Тъй като пирамидата на видимост се разширява, площта на сегментите, които са по-близо до камерата, може да бъде значително по-малка от площта на тези, които са по-далеч. Като се има предвид същата разделителна способност на картите на сенките, това означава по-висока разделителна способност за сенките от близките обекти. Статията, спомената по-горе в GPU Gems 3, предлага следната схема за изчисляване на разстоянията на разделяне на пирамидата на видимост:



Където аз– индекс на дяла, м– брой дялове, н– разстояние до най-близката отрязваща равнина, f– разстояние до далечната режеща равнина, λ – коефициент, който определя интерполацията между логаритмичната и равномерната скала на разпределение.

Общи в изпълнение
Алгоритъмът PSSM, внедрен в Direct3D 11 и OpenGL, има много общи неща. За да приложите алгоритъма, трябва да подготвите следното:
  1. Няколко карти на сенките (според броя на дяловете). На пръв поглед изглежда, че за да получите множество карти на сенки, трябва да нарисувате обекти няколко пъти. Всъщност не е необходимо да правите това изрично; ще използваме механизма за създаване на хардуерни екземпляри. За да направим това, имаме нужда от така наречения рендиращ текстурен масив и прост геометричен шейдър.
  2. Механизъм за отрязване на предмети. Обектите в света на играта могат да бъдат с различни геометрични форми и различни позиции в пространството. Разширените обекти могат да бъдат видими в няколко карти на сенки, малки обекти - само в една. Обект може да се появи директно на границата на съседни сегменти и трябва да бъде начертан с поне 2 карти на сенки. По този начин е необходим механизъм, който да определи в кое подмножество от карти на сенки попада даден обект.
  3. Механизъм за определяне на оптималния брой дялове. Изобразяването на карти на сенки за всеки сегмент на кадър може да бъде загуба на изчислителни ресурси. В много ситуации играчът вижда само малка част от света на играта пред себе си (например той гледа краката си или погледът му спира на стената пред него). Ясно е, че това зависи до голяма степен от вида на прегледа в играта, но би било хубаво да има такава оптимизация.
В резултат на това получаваме следния алгоритъм за генериране на матрици за изглед-проекция за изобразяване на карти на сенки:
  1. Ние изчисляваме разстоянията, за да разделим пирамидата на видимост в най-лошия случай. Най-лошият случай тук е, че виждаме сенки до далечната равнина на изрязване на камерата.

    Код

    void calculateMaxSplitDistances() ( float nearPlane = m_camera.getInternalCamera().GetNearPlane(); float farPlane = m_camera.getInternalCamera().GetFarPlane(); for (int i = 1; i< m_splitCount; i++) { float f = (float)i / (float)m_splitCount; float l = nearPlane * pow(farPlane / nearPlane, f); float u = nearPlane + (farPlane - nearPlane) * f; m_maxSplitDistances = l * m_splitLambda + u * (1.0f - m_splitLambda); } m_farPlane = farPlane + m_splitShift; }

  2. Определяме разстоянието между камерата и най-отдалечената видима точка на обекта, който хвърля сянка. Тук е важно да се отбележи, че обектите могат или не могат да хвърлят сенки. Например, плосък хълмист пейзаж може да бъде направен така, че да не хвърля сенки; в този случай алгоритъм за осветление може да бъде отговорен за засенчването. Само обекти, които хвърлят сенки, ще бъдат начертани в картата на сенките.

    Код

    float calculateFurthestPointInCamera(const matrix44& cameraView) (bbox3 scenebox; scenebox.begin_extend(); for (size_t i = 0; i< m_entitiesData.size(); i++) { if (m_entitiesData[i].isShadowCaster) { bbox3 b = m_entitiesData[i].geometry.lock()->getBoundingBox(); b.transform(m_entitiesData[i].model); scenebox.extend(b); ) ) scenebox.end_extend(); float maxZ = m_camera.getInternalCamera().GetNearPlane(); за (int i = 0; i< 8; i++) { vector3 corner = scenebox.corner_point(i); float z = -cameraView.transform_coord(corner).z; if (z >maxZ) maxZ = z; ) връща std::min(maxZ, m_farPlane); )

  3. Въз основа на стойностите, получени в стъпки 1 и 2, ние определяме броя на сегментите, от които наистина се нуждаем, и разстоянията на разделяне за тях.

    Код

    void calculateSplitDistances() ( // изчисляваме от колко карти на сенките наистина се нуждаем m_currentSplitCount = 1; if (!m_maxSplitDistances.empty()) ( for (size_t i = 0; i< m_maxSplitDistances.size(); i++) { float d = m_maxSplitDistances[i] - m_splitShift; if (m_furthestPointInCamera >= d) m_currentSplitCount++; ) ) float nearPlane = m_camera.getInternalCamera().GetNearPlane(); за (int i = 0; i< m_currentSplitCount; i++) { float f = (float)i / (float)m_currentSplitCount; float l = nearPlane * pow(m_furthestPointInCamera / nearPlane, f); float u = nearPlane + (m_furthestPointInCamera - nearPlane) * f; m_splitDistances[i] = l * m_splitLambda + u * (1.0f - m_splitLambda); } m_splitDistances = nearPlane; m_splitDistances = m_furthestPointInCamera; }

  4. За всеки сегмент (границите на сегмента се определят от близкото и далечното разстояние) изчисляваме граничния паралелепипед.

    Код

    bbox3 calculateFrustumBox(float nearPlane, float farPlane) ( vector3 eye = m_camera.getPosition(); vector3 vZ = m_camera.getOrientation().z_direction(); vector3 vX = m_camera.getOrientation().x_direction(); vector3 vY = m_camera. getOrientation().y_direction(); float fov = n_deg2rad(m_camera.getInternalCamera().GetAngleOfView()); float aspect = m_camera.getInternalCamera().GetAspectRatio(); float nearPlaneHeight = n_tan(fov * 0.5f) * nearPlane; float nearPlaneWidth = nearPlaneHeight * аспект; float farPlaneHeight = n_tan(fov * 0.5f) * farPlane; float farPlaneWidth = farPlaneHeight * аспект; vector3 nearPlaneCenter = eye + vZ * nearPlane; vector3 farPlaneCenter = eye + vZ * farPlane; bbox3 box; box. begin_extend(); box.extend(vector3(nearPlaneCenter - vX * nearPlaneWidth - vY * nearPlaneHeight)); box.extend(vector3(nearPlaneCenter - vX * nearPlaneWidth + vY * nearPlaneHeight)); box.extend(vector3(nearPlaneCenter + vX * nearPlaneWidth + vY * nearPlaneHeight));box.extend(vector3(nearPlaneCenter + vX * nearPlaneWidth - vY * nearPlaneHeight)); box.extend(vector3(farPlaneCenter - vX * farPlaneWidth - vY * farPlaneHeight)); box.extend(vector3(farPlaneCenter - vX * farPlaneWidth + vY * farPlaneHeight)); box.extend(vector3(farPlaneCenter + vX * farPlaneWidth + vY * farPlaneHeight)); box.extend(vector3(farPlaneCenter + vX * farPlaneWidth - vY * farPlaneHeight)); box.end_extend(); кутия за връщане; )

  5. Ние изчисляваме матрицата на сенките на проекционния изглед за всеки сегмент.

    Код

    matrix44 calculateShadowViewProjection(const bbox3& frustumBox) ( const float LIGHT_SOURCE_HEIGHT = 500.0f; vector3 viewDir = m_camera.getOrientation().z_direction(); vector3 size = frustumBox.size(); vector3 center = frustumBox.center() - viewDir * m_splitShift; center.y = 0; auto lightSource = m_lightManager.getLightSource(0); vector3 lightDir = lightSource.orientation.z_direction(); matrix44 shadowView; shadowView.pos_component() = център - lightDir * LIGHT_SOURCE_HEIGHT; shadowView.lookatRh(shadowView.pos_component( ) + lightDir, lightSource.orientation.y_direction()); shadowView.invert_simple(); matrix44 shadowProj; float d = std::max(size.x, size.z); shadowProj.orthoRh(d, d, 0.1f, 2000.0f); връщане на shadowView * shadowProj; )

Ние прилагаме изрязване на обекти, като използваме прост тест за пресичане на два гранични паралелепипеда (обект и сегмент от пирамидата на видимостта). Тук има една особеност, която е важно да се вземе предвид. Може да не виждаме обекта, но можем да видим сянката му. Не е трудно да се досетите, че с описания по-горе подход ще отрежем всички обекти, които не се виждат в основната камера, и няма да има сенки от тях. За да предотвратя това, използвах доста обичайна техника - разширих ограничителната кутия на обекта по посока на разпространение на светлината, което даде грубо приближение на областта от пространството, в която се вижда сянката на обекта. В резултат на това за всеки обект беше генериран масив от индекси на картата на сенките, в които този обект трябва да бъде изчертан.

Код

void updateShadowVisibilityMask(const bbox3& frustumBox, const std::shared_ptr & entity, EntityData& entityData, int splitIndex) ( bbox3 b = entity->getBoundingBox(); b.transform(entityData.model); // автоматично изчисление на сенчеста кутия lightSource = m_lightManager.getLightSource(0); vector3 lightDir = lightSource.orientation .z_direction(); float shadowBoxL = fabs(lightDir.z)< 1e-5 ? 1000.0f: (b.size().y / -lightDir.z); bbox3 shadowBox; shadowBox.begin_extend(); for (int i = 0; i < 8; i++) { shadowBox.extend(b.corner_point(i)); shadowBox.extend(b.corner_point(i) + lightDir * shadowBoxL); } shadowBox.end_extend(); if (frustumBox.clipstatus(shadowBox) != bbox3::Outside) { int i = entityData.shadowInstancesCount; entityData.shadowIndices[i] = splitIndex; entityData.shadowInstancesCount++; } }


Сега нека да разгледаме процеса на рендиране и частите, специфични за Direct3D 11 и OpenGL 4.3.
Внедряване на Direct3D 11
За да внедрим алгоритъма на Direct3D 11 ще ни трябва:
  1. Масив от текстури за изобразяване на карти на сенки. За да създадете този вид обект, има поле ArraySize в структурата D3D11_TEXTURE2D_DESC. Така че в C++ кода няма да имаме нищо като ID3D11Texture2D* array[N] . От гледна точка на Direct3D API, масив от текстури се различава малко от една текстура. Важна характеристика при използването на такъв масив в шейдър е, че можем да определим към коя текстура в масива ще нарисуваме този или онзи обект (SV_RenderTargetArrayIndex семантика в HLSL). Това е основната разлика между този подход и MRT (многобройни цели за изобразяване), при които един обект се рисува във всички определени текстури наведнъж. За обекти, които трябва да бъдат начертани в няколко карти на сенки наведнъж, ще използваме хардуерно инстанциране, което ни позволява да клонираме обекти на ниво GPU. В този случай обектът може да бъде изчертан в една текстура в масива, а неговите клонинги в други. Ще съхраняваме само стойността на дълбочината в картите на сенките, така че ще използваме формата на текстурата DXGI_FORMAT_R32_FLOAT.
  2. Специален пробник на текстура. В Direct3D API можете да зададете специални параметри за вземане на проби от текстура, което ще ви позволи да сравните стойността в текстурата с дадено число. Резултатът в този случай ще бъде 0 или 1, а преходът между тези стойности може да бъде изгладен от линеен или анизотропен филтър. За да създадете семплер в структурата D3D11_SAMPLER_DESC, задайте следните параметри:

    SamplerDesc.Filter = D3D11_FILTER_COMPARISON_MIN_MAG_LINEAR_MIP_POINT; samplerDesc.ComparisonFunc = D3D11_COMPARISON_LESS; samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_BORDER; samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_BORDER; samplerDesc.BorderColor = 1.0f; samplerDesc.BorderColor = 1.0f; samplerDesc.BorderColor = 1.0f; samplerDesc.BorderColor = 1.0f;
    Така ще имаме билинейно филтриране, сравнение с функцията „по-малко от“ и вземане на проби от текстурата при координати извън диапазона ще върне 1 (т.е. без сянка).

Ще извършим рендиране по следната схема:

Внедряване на OpenGL 4.3
За да реализираме алгоритъма на OpenGL 4.3, имаме нужда от всичко същото като за Direct3D 11, но има тънкости. В OpenGL можем да правим сравнимо извличане само за текстури, които съдържат стойност за дълбочина (например във формат GL_DEPTH_COMPONENT32F). Следователно ще рендираме само в буфера за дълбочина и ще премахнем записа в цвят (по-точно, ще свържем само масив от текстури към буфера на кадрите, за да съхраним буфера за дълбочина). Това, от една страна, ще ни спести малко видео памет и ще улесни графичния конвейер, от друга страна, ще ни принуди да работим с нормализирани стойности на дълбочината.
Параметрите за вземане на проби в OpenGL могат да бъдат обвързани директно с текстурата. Те ще бъдат идентични с тези, обсъдени по-рано за Direct3D 11.

Const float BORDER_COLOR = (1.0f, 1.0f, 1.0f, 1.0f); glBindTexture(m_shadowMap->getTargetType(), m_shadowMap->getDepthBuffer()); glTexParameteri(m_shadowMap->getTargetType(), GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(m_shadowMap->getTargetType(), GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(m_shadowMap->getTargetType(), GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); glTexParameteri(m_shadowMap->getTargetType(), GL_TEXTURE_COMPARE_FUNC, GL_LESS); glTexParameteri(m_shadowMap->getTargetType(), GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER); glTexParameteri(m_shadowMap->getTargetType(), GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER); glTexParameterfv(m_shadowMap->getTargetType(), GL_TEXTURE_BORDER_COLOR, BORDER_COLOR); glBindTexture(m_shadowMap->getTargetType(), 0);
Интересен е процесът на създаване на масив от текстури, който е представен от триизмерна текстура в OpenGL. Не е създадена специална функция за създаването му, и двете са създадени с помощта на glTexStorage3D. GLSL еквивалентът на SV_RenderTargetArrayIndex е вградената променлива gl_Layer.
Схемата за изобразяване също остава същата:

проблеми

Алгоритъмът за картографиране на сенки и неговите модификации имат много проблеми. Често алгоритъмът трябва да бъде внимателно настроен за конкретна игра или дори за конкретна сцена. Можете да намерите списък с най-често срещаните проблеми и начини за разрешаването им. При прилагането на PSSM срещнах следното:

производителност

Измерванията на производителността бяха извършени на компютър със следната конфигурация: AMD Phenom II X4 970 3,79 GHz, 16 Gb RAM, AMD Radeon HD 7700 Series, работещ под Windows 8.1.

Средно време за кадър. Direct3D 11 / 1920x1080 / MSAA 8x / цял екран / малка сцена (~12k полигони на кадър, ~20 обекта)

Средно време за кадър. OpenGL 4.3 / 1920x1080 / MSAA 8x / цял екран / малка сцена (~12k полигони на кадър, ~20 обекта)

Средно време за кадър. 4 разделяния / 1920x1080 / MSAA 8x / цял екран / голяма сцена (~1000k полигони на кадър, ~1000 обекта, ~500 екземпляра на обект)

Резултатите показаха, че на големи и малки сцени внедряването на OpenGL 4.3 обикновено е по-бързо. Тъй като натоварването на графичния тръбопровод се увеличава (увеличаване на броя на обектите и техните екземпляри, увеличаване на размера на картите на сенките), разликата в скоростта на работа между реализациите намалява. Свързвам предимството на внедряването на OpenGL с различен метод за генериране на карти на сенки от Direct3D 11 (използвахме само буфер за дълбочина, без да записваме цвят). Нищо не ни пречи да направим същото в Direct3D 11, като същевременно се примирим с използването на нормализирани стойности на дълбочината. Този подход обаче ще работи само докато не искаме да съхраним някои допълнителни данни или функция на стойността на дълбочината в картата на сенките вместо стойността на дълбочината. А някои подобрения на алгоритъма (например Variance Shadow Mapping) ще ни бъдат трудни за изпълнение.

заключения

Алгоритъмът PSSM е един от най-успешните методи за създаване на сенки в големи открити пространства. Базира се на прост и ясен принцип на разделяне, който може лесно да се мащабира чрез увеличаване или намаляване на качеството на сенките. Този алгоритъм може да се комбинира с други алгоритми за картографиране на сенки, за да се получат по-красиви меки сенки или по-физически правилни. В същото време класовите алгоритми за картографиране на сенки често водят до появата на неприятни графични артефакти, които трябва да бъдат елиминирани чрез фина настройка на алгоритъма за конкретна игра.

Тагове:

  • Картографиране на сенки
  • PSSM
  • Direct3D 11
  • OpenGL 4
Добави тагове

Четвърти блог за разработчици: Нови графични функции

В първия дневник за актуализиране на графичния двигател говорихме накратко за някои от новите графични подобрения, които скоро ще бъдат добавени към играта. Освен това сме заявили, че повечето от тези подобрения ще бъдат наравно с модерни двигатели за игри като Unity 5, Unreal 4 или CryEngine 3. Но какво всъщност означава това?

Първо, искаме да разберете, че процесът на актуализиране ще се извърши постепенно и не всички карти, герои, текстури на оръжия и обекти ще бъдат актуализирани веднага. Повечето от тях ще продължат да работят с текущите активи на играта, но ние ще ги актуализираме с течение на времето, за да придадем на Combat Arms наистина актуализиран вид.

Струва си да се отбележи, че за да накараме много от тези графични възможности да работят на толкова стар двигател, като в същото време поддържаме обратна съвместимост със стария графичен режим и ресурси, ни се наложи да направим много интересни и понякога луди заобиколни решения, ограничени до възможностите на DirectX 9. Беше много смешно!

Динамично осветление и сенки

Оригиналният двигател на Lithitech Jupiter имаше ограничена поддръжка за динамично осветление и сенки, въпреки че предлаганото от двигателя беше доста напреднало за ерата, в която беше разработен. По принцип в оригиналния графичен двигател на Lithtech Jupiter осветлението и засенчването бяха напълно статични, което означава, че бяха предварително изчислени и съхранени като текстура, която се използваше при рендиране на геометрията на картата. Въпреки това дори статичното осветление в някои моменти им позволява да създават динамично осветени сцени върху определени обекти, като модели на герои и оръжия. Тъй като динамичното осветление, използвано за всеки връх върху обекти, различни допълнителни детайли и неравности също трябваше да бъдат предварително изчислени и изпечени директно върху дифузните текстури. И тъй като са изпечени, те не могат динамично да взаимодействат с различни източници на светлина и често не се вписват в условията на осветление. Това прави картината да изглежда много плоска и остаряла за 2017 г.

Най-важното подобрение, което успяхме да приложим, беше да комбинираме както статичната геометрия на картата, така и обектите, получаващи напълно динамично осветление и сенки. Динамичното осветление наистина ви позволява да изобразите сцена с осветление пиксел по пиксел, отражения, акценти, динамични сенки и карти на неравности.

Докато въвеждането на единичен динамичен източник на светлина първоначално не беше толкова трудно, предизвикателствата възникнаха от необходимостта да се поддържат едновременно множество динамични източници на светлина по ефективен начин. Поддръжката на множество динамични източници на светлина се превърна в основна характеристика на почти всеки модерен двигател за игри. Единственият начин, по който двигателят на Lithtech поддържа рендиране на множество динамични светлини, е по същество да преначертае цялата сцена няколко пъти, по веднъж за всяка светлина на картата. Това е донякъде преувеличено, тъй като Lithtech е в състояние да групира геометрията на картата в блокове, които могат да бъдат направени от ограничаваща светлинна сфера, и само тези блокове на картата ще трябва да бъдат преначертани. Но това все още изисква голямо натоварване на процесора, за да изобрази сцената многократно и поставя още повече ограничения върху това колко сложна е геометрията на картата и колко обекти могат да бъдат показани на екрана наведнъж.

Започнахме, като в началото имахме само основната насочена слънчева светлина като единствен източник на динамична светлина. Всички други вътрешни всепосочни и точкови източници на светлина бяха оставени статични. Но много от локациите на играта в Combat Arms са частично или изцяло разположени в сгради, така че разликата между вътрешно статично и външно динамично осветление беше твърде забележима.

И така, за динамично осветление, използващо множество източници на светлина, трябваше да се направят големи промени в начина, по който двигателят изобразява сцената и борави със самата светлина. За да направим това, използвахме техника за изобразяване, известна като отложено засенчване. Темата за отложеното осветление и засенчване може да бъде доста широка и ние накратко я споменахме в първата публикация в блога на разработчиците. По принцип той позволява цялото динамично осветление да бъде изтласкано в сферата на изобразяване след обработка, което е напълно независимо от сложността на сцената и може да се обработва почти изцяло от графичния процесор с много малко натоварване на процесора.

Имайки предвид всички тези оптимизации, успяхме да внедрим шейдър за осветление със сложна физика. След това обстойно тествахме този модел на осветление, сравнявайки го с начина, по който подобни сцени биха били изобразени в други съвременни двигатели на игри като Unity 5 и Unreal 4, както и напълно изобразени с лъчи сцени, създадени с помощта на професионално офлайн изобразяване. Ограничихме се само до това, което можехме да внедрим в реално време с модерен графичен хардуер, използвайки модерни шейдъри за осветление. Резултатите са доста сравними с изобразяването на лъчи, като основните разлики са точността на отражението и затихването на осветеността.

Нови шейдъри за динамично осветление в Combat Arms:

Проследена с лъчи версия на сцената:

Карта със сянка

При внедряването на динамични сенки се сблъскахме с редица предизвикателства, за да постигнем най-съвременното, напълно динамично засенчване в Combat Arms. В оригиналния двигател на Lithtech повечето сенки се пекат в текстури на статично осветление, използвани при изобразяване на геометрията на картата. Ето защо не всички обекти хвърлят сянка, особено динамичните обекти, защото сянката е фиксирана и не може да се променя. Въпреки че Lithtech има функция, която ви позволява да създавате динамични сенки върху определени обекти, тя не е използвана много в Combat Arms. Освен това тази функция е твърде ограничена в своя обхват и самите динамични обекти не могат да получават сенки.

В крайна сметка решихме да използваме напълно динамична каскадна карта на сенките (CSM) за основния източник на насочена светлина от слънцето и частично динамично решение за многопосочни светлини и източници на светлина, използвайки предварително изчислена многопосочна карта на сенките, която може да се приложи както към световната геометрия, така и към динамичните обекти. Това е подобно на начина, по който други модерни двигатели за игри осигуряват динамично засенчване.

Като цяло, какво е Shadow Card? По същество това е много умен трик, който игрите и програмите за рендиране използват, за да симулират GPU-ускорено динамично засенчване. https://en.wikipedia.org/wiki/Shadow_mapping.

Алгоритъмът за изобразяване на сянка основно се занимава с необходимостта от изобразяване на сцената от гледна точка на източник на светлина върху текстура, като я използва като входна точка за шейдъра за пикселно осветление и след това използва тази текстура, за да изчисли от GPU дали пикселът е в сянка или не.

В играта текстурата на картата на сенките изглежда така:

Моля, обърнете внимание, че тази текстура има не 1, а 4 карти на сенките. Всяка от тези карти на сенки се нарича каскада на карти на сенки. С увеличаване на разстоянието до наблюдаваната повърхност се използва по-голяма каскада, но с по-ниска разделителна способност. Това позволява на сенките да се простират много далеч, но все пак да се поберат в една текстура с фиксиран размер. В този случай сенките в близост до наблюдателя ще имат по-висока разделителна способност. Разделителната способност на картата на сенките е пряко свързана с това колко остри и точни могат да бъдат сенките.

Тъй като картата на сенките е просто още една камера в сцената, тя може да се визуализира динамично в реално време. Настройките за качество на сенките ще повлияят на резолюцията на текстурата на картата на сенките.

Ето как изглежда решението за карта на сенките, когато е филтрирано.

Филтриране на картата на сенките

Използването само на карта на сенките може да доведе до много груби сенки. И макар понякога да изглеждат добре, това не е реалност.

В реалния свят сенките не винаги са твърди или меки, те се променят в зависимост от размера на източника на светлина и разстоянието от осветения обект. Можете да видите примери на снимката:

Забележете как на тези снимки сенките стават по-меки, когато се отдалечават от обектите, които ги хвърлят. Повечето други съвременни игри все още използват прост метод за филтриране на засенчване, наречен Percentage Closer Filtering или PCF, който прилага фиксирана стойност на твърдост или мекота към всички сенки.

Тези екранни снимки от много модерните игри Doom и Overwatch показват как повечето игри правят просто филтриране на сенки с помощта на PCF.

Въпреки това, в Combat Arms решихме да внедрим по-усъвършенствана технология за филтриране на сенки, която ще бъде по-близо до това, което виждаме в реалния живот. В играта ние симулираме това с помощта на технология, разработена от NVidia, наречена Closer Soft Shadows (PCSS).

Въпреки че тази технология беше въведена още през 2005 г., едва сега графичният хардуер стана достатъчно мощен, за да използва този метод, а съвременните игри започнаха да го използват интензивно за филтриране на карти на сенки едва през последните години. Към момента на писане на този блог тази технология все още не е налична в Unreal 4 или Unity 5. Въпреки че технически погледнато, Unreal 4 предоставя алтернативно решение, наречено дистанционно проследяване на лъчи, но е ограничено само до разрешаване на статична геометрия за хвърляне на сенки.

PCSS деактивиран:

PCSS активиран:

Ще се приложи фино филтриране с PCSS, когато настройките за качество на сенките са зададени на високо. Освен това PCSS в момента се използва само за основна насочена слънчева светлина при всички нива на качество. За съжаление, PCSS не е съвместим с хардуерно ускорено филтриране на сенки. Shader Model 3 DirectX 9 не поддържа инструкциите за шейдър Gather4, които обикновено се използват в пикселните шейдъри DirectX 10+/Shader Model 4+ за филтриране на картата на сенките. Поради оперативното натоварване на PCSS, използвайки пикселния шейдър Shader Model 3, филтрирането с антиалиас се използва за намаляване на натоварването на GPU.

Всепосочно картографиране на сенките

При многопосочните източници на светлина нещата са малко по-сложни. Тъй като те хвърлят сенки във всички посоки, създаването на карти на сенките за тях не е толкова лесно, тъй като сцената трябва да бъде изобразена с помощта на някаква 360° камера. Това обикновено включва изобразяване на сцената в множество посоки от позицията на източника на светлина. Въпреки това е трудно да се мащабира сцена, когато има много такива източници на светлина. Така че за това използвахме предварително изчислена карта на сенките, където се изчислява само веднъж, когато картата се зарежда, вместо всеки кадър. Предварително изчислената карта на сенките може да хвърля сенки върху динамични обекти в сцената, но динамичните обекти в сцената няма да хвърлят сенки. За да се заобиколи това ограничение, естествената функция за сянка на обекти от двигателя на Lithtech се използва за даване на сенки на обекти от предварително изчислени многопосочни карти на сенките. Ние също така комбинираме това с проследяване на сенки в екранно пространство, за да дадем на обектите подробни собствени сенки и сенки за контакт.

Интересен пример за това как се използва карта на сенките за проектиране на многопосочна карта на сенките в една текстура:

Това използва изцяло 360° проекционен метод, известен като параметризация на сферичен октаедър или понякога наричан „октаедрично картографиране“, където сферата се картографира към една текстура въз основа на нейната проекция върху лицето на октаедъра.

Традиционните многопосочни карти на сенки използват кубична карта, която изисква поне 6 различни текстури, за да представи пълна 360° всепосочна карта на сенки, но с тази проекция на карта се използва само 1 текстура. Този метод също така произвежда по-малко изкривяване от повечето други сферични 2D методи за проектиране и за разлика от неопакована кубична карта, той се вписва перфектно в една квадратна текстура. Много съществуващи карти в играта използват голям брой многопосочни светлини като основни източници на светлина и това позволява на много от тях да поддържат и динамично засенчване в реално време.

Нека обобщим

Ние вярваме, че тази комбинация от технологии за осветяване и засенчване ще даде на играта много модерен облик за 2017 г. и че нашите решения са доста конкурентни на това, което другите двигатели на игри предлагат днес. Въпреки че тези промени сами по себе си не са достатъчни за „модернизиране“ на играта, все още имаме много работа за вършене, за да подобрим текстурите и активите, които ще се възползват напълно от новите функции.

Разбира се, това не са всички промени, това беше само задълбочен поглед върху техническите детайли на внедряването на динамично осветление и засенчване в предстоящата актуализация на Combat Arms. Освен това е важно да се отбележи, че показаните екранни снимки са направени с помощта на компилация с текущите активи, за да се демонстрират графичните функции. Те може да не отразяват точно крайното графично ниво след пускането на актуализацията.

Трябва също да ви напомня, че актуализираните графични настройки не са задължителни и ще можете да превключвате между версиите на двигателя, след като актуализацията бъде пусната. Ние разработваме тези графични подобрения въз основа на възможностите на съвременните графични устройства от среден и висок клас, които са актуални за 2016 г. Искаме двигателът на играта да може да се възползва напълно от съвременните графични процесори, за да предостави възможно най-доброто визуално качество. Все още непрекъснато сравняваме и оптимизираме нови графични функции, но имайте предвид, че малко по-старият или по-евтин хардуер може да е в състояние да изпълнява нови графични опции само при по-ниски настройки или разделителни способности. Ние ще продължим да поддържаме наследения графичен двигател, така че играчите с по-стар или по-малко мощен хардуер или тези, които просто предпочитат класическия стил Combat Arms, могат да продължат да се наслаждават на играта както преди.

Най-добри поздрави, екип на Combat Arms!

Картографирането на сенки е може би най-трудната част от създаването на визуално представяне на обект. Използваме ги, за да получим изпечена светлина и сянка.
Те трябва да бъдат уникално разопаковани, така че всяка част от модела да има свое собствено място в UV пространството, за да се получи правилната информация за светлина и сенки.
Важно е да запомните, че резолюцията на картата на сенките е малка в сравнение с размера на UV пространството.
Също така е важно да се разбере, че колкото повече трябва да се оптимизира дадено ниво, толкова по-ниска е разделителната способност на светлинните карти, която понякога достига до 8 на 8 или 16 на 16 в случай на по-малки обекти.
Тази тенденция изисква да оставим много допълнително пространство около всяка секция на обекта, така че областите, които са тъмни
не повлия на светлите точки и не разруши илюзията за визуална коректност на сенките в играта.

Има 3 основни начина за създаване на такова почистване:

КУТИЯ РАЗОПАКОВАНЕ

Това често е най-надеждният метод за създаване на оформление на обект, тъй като повечето модели на околната среда са близки по форма до блокове, които са комбинирани в някакъв вид структура.
Непрекъснатата мрежа (мрежа, в която няма части, отделени от основната част) често е много полезно решение при конструирането на мрежа,
Това решение ще помогне да се осигури по-ефективно разпределение на геометрията на мрежата в UV пространството.
Това също ще работи добре дори с карта на сенките с ниска разделителна способност, тъй като тогава ще формира един градиент от тъмно към светло.
Това е за разлика от фрагментирано сканиране, при което резултатът ще изглежда по-двусмислен и може да се наложи да увеличите разделителната способност на картата на сенките, за да противодействате на ефекта от острите преходи.
Трябва да се опитаме да избегнем това, където можем. За съжаление, понякога не е възможно да се използва по-ниска разделителна способност или едно геометрично сканиране.

ПЛАНАРНО РАЗГЛЕЖДАНЕ

Този метод е особено полезен за плоски конструкции, като стени с няколко фаски или екструзии. Също така е много полезно за големи части от фасади на сгради, като например жилищни сгради.
Планарнаще се разгъне много по-добре, ако използвате непрекъсната геометрия, защото тук въпросът ще бъде само за „отпускане“ на сканиращата мрежа.
Понякога също така е добро правило да се уверите, че има повече хоризонтално пространство при сканиране като това, отколкото вертикално, тъй като хвърлянето на сянка обикновено е отстрани под малко по-висок ъгъл.
а не право надолу. По този начин по-голямото хоризонтално пространство предоставя по-големи възможности за създаване на по-резки сенки, поради тенденцията на дизайнерите да избират осветление под ъгъл,
за създаване на по-интересни сенки от осветлението отгоре надолу.

ЦИЛИНДРИЧНО РАЗГЛЕЖДАНЕ

Повечето други форми могат да се разглеждат като вариации на цилиндричната форма, освен ако разбира се не са близки до паралелепипеди или равнини.
Цилиндричното развитие е добре да се използва за много структури, които имат предна част и страни, но нямат гръб, в противен случай бихме използвали метода КУТИЯ РАЗОПАКОВАНЕ.

Примери

Беше непрекъсната мрежа, така че беше лесно да се разширява с нея КУТИЯ РАЗОПАКОВАНЕи просто го разположете хоризонтално, за да използвате възможно най-много от пространството на картата на сенките.
Долните повърхности, които биха се виждали в средното изображение, са премахнати, тъй като те почти винаги ще бъдат черни.
и ако бяха свързани с останалата част от сканирането, сенките от тях просто щяха да се просмукват на тъмни петна по стените, където това не трябва да бъде. Същото важи и за горните лица.
Само дето винаги щяха да са леки.


Този метод на разопаковане ни позволява да имаме почти перфектна карта на сенките в играта с разделителна способност 32 на 32. Геометрията няма шевове. Там, където трябва да има сянка, виждаме тънки черни линии, а където не трябва да има, няма.


Тук виждаме, че е необходимо да се използва възможно най-много място, тъй като картата на сенките ще покрие цялото сканиране във всеки случай.
Следователно ще видите значителна разлика между аспектното съотношение на обект 1 към 1 и 1 към 7. Можете също така да видите, че някои части от сканирането са разделени тук и се отдалечават от основната мрежа.
Това се прави, защото тези части винаги ще останат в сянка. Те не трябва да засягат останалата част от картата на сенките.


Дори на големи фасади като тази, Планарнапоказва добри резултати. Тази мрежа е непрекъсната, което помага на нашата работа,
но в този случай всичко ще работи по същия начин, дори ако сканирането е разделено на няколко вертикални или хоризонтални ивици, въпреки че е необходимо да се направят малки вдлъбнатини между тях.


Можете да видите тук, тясната геометрия улесни поставянето на UV. Можете също така да видите, че има вдлъбнатини между частите на сканирането, така че тъмните зони да не влияят на светлите.
Колкото по-ниска е резолюцията на картата, толкова повече вдлъбнатини трябва да направите.


Можете да видите някои доста агресивни изкривявания върху пресичащите се вертикални части, които държат парапета заедно.
Можете да видите, че централната опора е разделена на две части вместо на три, сякаш я изрязваме по ръбовете на централната част. Това се прави, за да се намали броят на шевовете и да се осигури гладко осветление на по-голяма площ.


Някои проекти не успяват да следват тези прости правила, както е на екранната снимка по-долу.


Когато има толкова много отделни елементи, нямаме друг избор, освен да увеличим разделителната способност на текстурите, в противен случай ще загубим много място за подложките между елементите за сканиране, ще изглежда ужасно в играта.
Така че резолюцията на картите на сенките беше повишена до 128 на 128, но все още не изглежда перфектно, но все пак не толкова, че да разруши напълно визуалния образ на обекта в играта.


Понякога е лесно да разширите обект, достатъчно е да го разделите на няколко разумни части. И след това просто „отпуснете“ почистването. Чудесен пример е обектът по-долу.


Този дизайн е по същество цилиндър с плоска основа, така че се използват тези два основни метода за разопаковане на обект.
Планарназавърта части от геометрията надолу по оста Z и след това прилага модификатор за „релаксация“ и коригира малко позициите на върховете, за да се увери, че нищо не получава твърде малко покритие.
В средата е подобен калъф на основата, тук централната част е разделена и използвана Планарнавместо Цилиндричназа да се осигури по-голяма зона на покритие.
Както винаги, ние сме по-загрижени за покритието, отколкото за съотношението 1: 1. Голямо предимство е да поставите шевовете на действителните им места, това ще позволи на сенките да изглеждат по-естествени.
Ако вашият обект има дълбоки прорези, изключително остри геометрични фуги, тогава това е отлично място за полагане на шев тук, ако разбира се е необходимо.

Индекс на координатите на Lightmap

По подразбиране първият набор от UV (индекс 0) на статичната мрежа ще се използва при създаването на картата на сенките за статично осветление.
Това означава, че същият набор от координати, които се използват за нанасяне на материали върху мрежата, ще се използва и за статично осветление.
Този метод доста често не е идеален. Една от причините за това е, че UV-ите, използвани за генериране на картата на сенките, трябва да бъдат уникални.
което означава, че всяко лице на мрежата не трябва да припокрива друга повърхност в UV пространството. Причината за това е съвсем очевидна: ако лицата се припокриват едно с друго на UV картата,
частта от картата на сенките, съответстваща на това пространство, ще бъде приложена и към двете лица. Това ще доведе до неправилно осветление и появата на сенки там, където по принцип не трябва да съществуват.
Статичните мрежи имат свойството LightmapCoordinateIndex, което ви позволява да използвате дадено UV сканиране за карта на сенките. Задайте това свойство да сочи към набор от UV, които са правилно конфигурирани за осветление.

UV диаграми и подложка

Групи от изолирани триъгълници със съседни UV се наричат ​​UV диаграми.

Трябва да разделите сканирането на диаграми и да ги поставите отделно, ако искате да изключите влиянието на сенките на една диаграма върху друга. Също така, когато правите отстъп, трябва да запомните едно просто правило:
Размерът на отстъпа трябва да бъде по-голям от 4x4 тексела, тъй като DXT компресията работи с блокове с точно този размер.

  1. Изхабена вдлъбнатина
  2. Задължителен отстъп

Това означава, че за карта на сенките с резолюция 32, подложката между частите на UV картата трябва да бъде 12,5% от общото UV пространство.
Имайте предвид обаче, че използването на твърде много подложки между части от UV ще доведе до загуба на памет на картата на сенките при по-високи разделителни способности.
Колкото по-близо можете да получите UV диаграмите, толкова по-добре. Това ще намали количеството загубена памет.


Това далеч не е идеалното разгръщане.

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


Най-добрият начин да създадете карта на мрежа за карта на сенките е да моделирате цялата мрежа като един непрекъснат елемент или да създадете мрежата на ръка.


Това ще доведе до едно измитане, което няма почти никакви шевове и е много по-ефективно.

Крайният резултат е мрежа, която свети правилно без никакви артефакти.


Допълнително предимство на този метод е, че обикновено намалява броя на върховете и триъгълниците, необходими за даден модел.


КАТЕГОРИИ

ПОПУЛЯРНИ СТАТИИ

2023 “kingad.ru” - ултразвуково изследване на човешки органи