.td_uid_42_5cd3d68242962_rand.td-a-rec-img{text-align:left}.td_uid_42_5cd3d68242962_rand.td-a-rec-img img{margin:0 auto 0 0}Наскоро участвах в състезанието за демосцени

...
.td_uid_42_5cd3d68242962_rand.td-a-rec-img{text-align:left}.td_uid_42_5cd3d68242962_rand.td-a-rec-img img{margin:0 auto 0 0}Наскоро участвах в състезанието за демосцени
Коментари Харесай

Демосцената Newton Protocol или какво може да се побере само в 4 KB

.td_uid_42_5cd3d68242962_rand.td-a-rec-img{text-align:left}.td_uid_42_5cd3d68242962_rand.td-a-rec-img img{margin:0 auto 0 0}
Наскоро участвах в надпреварата за демосцени Revision 2019 в категорията „ PC 4k intro “ и моето демо зае първото място. Аз направих кода и графиката, а dixan съчини музиката. Основното вярно в това съревнование е да се сътвори осъществим файл или уеб уебсайт с размер едвам 4096 байта . Това значи, че всичко би трябвало да се генерира благодарение на математика и логаритми, тъй като по никакъв различен метод няма по какъв начин да се компресират изображения, видео и аудио в толкоз малко памет. Тук ще опиша рендирането на моята демосцена Newton Protocol . По-горе може да бъде забелязан крайния резултат А ето тук може да се види по какъв начин изглеждаше всичко по време на Revision.

Изключително известна в дисциплината 4k intro е техниката Ray marching distance fields , тъй като дава опция за образуването на комплицирани форми единствено с няколко реда програмен код. Но този способ е присъщ с прекомерно ниската си скорост на работа. За рендирането на подиуми е належащо да се намерят другите точки на секване на лъчите със сцената – да вземем за пример, на виртуалния лъч от камерата, както и лъчите от източниците на светлина до обектите, с цел да може вярно да се изобрази осветяването. От друга страна, при потреблението на технологията за трасиране на лъчите ( ray tracing ), може да се откри точното секване посредством инспекцията на всеки обект по няколко пъти. Но в този случай, броят на генерираните фигури е доста стеснен, тъй като за изчсляването на другите пресичания на лъчите е нужна математическа формула за всеки вид фигури.

В тази демосцена аз желаех да симулираm напълно тъкмо осветление. За тази цел в сцената би трябвало да бъдат отразени милиони лъчи и за реализиране на този резултат разумния избор бе рейтрейсинга. Ограничих се с изобразяването на единствено една фигура – сфера, тъй като за нея пресичането на лъчите се пресмята относително елементарно. Дори и стените в това демо са доста огромни сфери. Освен това, по този метод се опрости и симулацията на физиката – задоволително бе да се отчетат единствено колизиите сред сферите.
.td_uid_41_5cd3d682424ee_rand.td-a-rec-img{text-align:left}.td_uid_41_5cd3d682424ee_rand.td-a-rec-img img{margin:0 auto 0 0}
За да илюстрирам обемa на кода, побран в 4096 байта, по долу представям цялостния сорс код на тази демосцена. Всичките елементи, като се изключи HTML в края, са компресирани като PNG изображение, с цел да може да се понижи техния размер. Без тази компресия кодът щеше да заеме съвсем 8900 байта. Частта с име Synth е орязана версия на SoundBox. За пакетирането на кода в този минимизиран формат, използвах Гугъл Closure Compiler и Shader Minifier. В края съвсем всичко е компресирано в PNG благодарение на JsExe. Пълният конвейер на компилацията може да се види в моята предходна 4К демосцена Core Critical, като тук съм употребявал напълно същия код.
 Музиката и синтезаторът напълно са написани на JavaScript. Делът на WebGL е разграничен на две елементи (показани са със зелен цвят), като те служат за конфигурация на конвейерите на рендера. Елементите на физиката и трасирането на лъчите са GLSL шейдъри. Останалата част от кода е кодирана като PNG изображение, а HTML е прибавен в края на това изображение без никакви промени. Браузърът пренебрегва данните на изображението и извършва единствено HTML кода, който от своя страна декомпресира PNG формата назад в JavaScript код и го изпълняваКонвейерът на рендирането
В изображението по-долу е показан конвейера на рендирането. Той е формиран от две елементи. Първата част на този конвейер е емулатор на физиката. В демосцената вземат участие 50 сфери, които се сблъскват една с друга в една виртуална стая. Самата стая е формирана от 6 сфери с друг размер, с цел да се сътвори по-нестандартно пространство. Двата източника на светлина, ситуирани в горните ъгли също са сфери – т.е., в цялото демо вземат участие общо 58 сфери.

Втората част на контейнера включва трасирането на лъчите, което рендира цялата сцена. На показаната нагоре скица е показано рендирането на един кадър в t миг от времето. Емулаторът на физиката взема предходния кадър (t-1) и емулира неговото настоящо положение. Алгоритъмът за трасиране на лъчите взема настоящата позиция и позицията от предходния кадър, с цел да може да реализира самото рендиране. След това, по време на постобработката се комбинират предходните 5 фрагмента с настоящия кадър, с което мощно се понижава равнището на шума. Едва по-късно се показва готовия резултат.

Алгоритъмът за емулиране на физиката е много банален и в интернет могат да бъдат открити доста материали за основаване на примитивна емулация на физичните закони за сферите. Позицията, радиусът, скоростта и масата на сферите се съхраняват в две текстури с резолюция 1х58. Използвах функционалността Webgl 2, даваща опция за рендиране на няколко обекта по едно и също време и ето за какво, данните на две от текстурите се записват по едно и също време. Същата функционалност се употребява и в логаритъма за трасиране на лъчите, за основаване на три текстури. Webgl не дава никакъв достъп до API за технологиите за трасиране на лъчите NVidia RTX и DirectX Raytracing (DXR) – ето за какво, всичко трябваше да се направи от нулата.
Трасирането на лъчите
Самото трасиране на лъчите е задоволително примитивна техника. Ние пропущаме в сцената виртуален лъч, който се отразява 4 пъти и в случай че попадне в източник на светлина, то цветът на отразяването се натрупва. В противоположен случай имаме черен цвят. В тези 4096 байта (включващи музика, синтезатор, физика и рендиране) няма място за потребление на комплицирани логаритми, които биха ускорили трасирането на лъчите. Ето за какво, тук употребявам метода на грубата мощ за инспекцията на всички разновидности. Всичките 57 сфери се ревизират за секване с всеки виртуален лъч, без да се вършат каквито и да било оптимизации за изключване на някои техни елементи. Това значи, че с цел да реализираме 60 фрагмента в секунда при 1080р резолюция е задоволително да се употребяват единствено от 2 до 6 виртуални лъча или семпъла на пиксел. А това е напълно незадоволително за основаването на гладко осветление на обектите.
 1 кадър на пиксел
Как да се оправим с това? В началото се стопирах на логаритъма за трасиране на лъчите, само че той и по този начин бе банален до краен лимит. Успях леко да повиша неговата продуктивност, като заобиколих случаите, когато лъчът минава през вътрешността на сферите, само че това няма по какъв начин да се употребява в този случай, тъй като в нашата демосцена вземат участие единствено непрозрачни обекти. Но не се получи.
 6 фрагмента на пиксел
Съседните пиксели би трябвало да имат сходна осветеност и за какво да не използваме това свойство при изчисляването осветеността на единичния пиксел? Ние не желаеме да размиваме текстурите, а единствено осветяването и по тази причина те би трябвало да се рендират в обособени канали. Също по този начин, не желаеме да получим размити обекти и би трябвало да отчитаме техните идентификатори, с цел да знаем кои тъкмо пиксели можем да размазваме от позиция на техните изображения.

Също по този начин, имаме отразяващи светлината обекти, а защото имаме потребност от ясни отблясъци, би трябвало да разберем ID на първия обект с който ще се сблъска лъча, което напълно не е елементарно. Аз използвах частния случай при напълно чисти отражателни материали, с цел да мога да включа в канала на идентификаторите на обектите и ID идентификатора на първия и втория обекти, забележими в отраженията. В този случай, размиването може да изглажда осветяването на обектите в отраженията, като в това време се резервират границите на самите обекти.
 Каналът на текстурите, който не би трябвало да се размива  Тук аленият канал съдържа ID на първия обект, зеления – на втория и синия – на третия обект. В кода те всички се записват в едно float число, в което в цялата част са записани идентификаторите на обектите, а дробната отбелязва грапавината (roughness)
Обектите в демосцената са с друга неравност (някои сфери са грапави, други разсейват осветяването, а трети са с огледално отражение). Ето за какво се употребява грапавината за ръководството на радиуса на размиването. В демото няма дребни елементи и за размиването се употребява огромно ядро с размер 50х50 и тегло във тип на противоположни квадрати. По този метод се получава задоволително безпрепятствено изображение, само че към момента доста добре се виждат многото артефакти, изключително при придвижване.

Когато обектите се намират на сцената и заснемащата камера постепенно се движи, осветеността във всеки един кадър би трябвало да остане непрекъсната. Ето за какво ще би трябвало да изпълним размиване освен в XY координатите на екрана, а и по време. Ако предположим, че осветеността няма да се промени изключително доста в границите на 100 милисекунди, то тя може да бъде осреднена в границите на 6 фрагмента.
 Канал за скоростите на пикселите, в който се вижда къде се е намирал пикселът в последния кадър, въз основата на придвижването на обекта и на камерата  За да избегнем взаимното размиване на обектите, още веднъж използваме стек за техните идентификатори. В този случай се съобразяваме единствено с първия обект, с който се е сблъскал лъчът. По този метод реализираме изглаждане (антиалайзинг) в рамките на обекта – т.е.,в отраженията
Разбира се, пикселът от предния кадър може да се окаже незабележим – да е прикрит зад различен обект или да се намира отвън полето на видимост на камерата. В тези случаи не можем да използваме предходната информация. Тази инспекция се прави настрана за всеки един кадър, а ние натрупваме информацията от 1 до 6 фрагмента за всеки пиксел и използваме единствено тези пиксели, които е належащо. По-долната илюстрация демонстрира, че за бавните обекти това не е проблем.
 Когато обектите се движат и разкриват нови области от сцената, ние нямаме 6 предходни фрагмента с информация, с цел да я усредним за пикселите в тези области. Тук са показани областите, в които има шест фрагмента (бял цвят), както и области, в които информацията е незадоволителна (потъмняващите отенъци)  Размитото осветление е усреднено за 6 фрагмента. Артефактите са към този момент съвсем незабележими и резултатът е постоянен с течение на времето
Комбинирайки всичко това, получаваме готовото изображение. Осветяването се размива по прилежащите пиксели, а текстурите и отраженията остават ясни и детайлни. С течение на времето се употребява усредняване на всеки 6 фрагмента, с което се основава безпрепятствено и устойчиво във времето изображение.
 Готовото изображение
Като цяло съм доста удовлетворен от тази демосцена. Успях да вмъкна в нея всичко, което бях възнамерявал. Въпреки съвсем незабележимите бъгове, резултатът е доста първокласен. В бъдеще премислям да изчистя бъговете и да подобря изглаждането. Мисля да опитвам с въвеждането на бистрота, motion blur, с по-различни фигури и с промяна на обектите.
 .td_uid_43_5cd3d68242d28_rand.td-a-rec-img{text-align:left}.td_uid_43_5cd3d68242d28_rand.td-a-rec-img img{margin:0 auto 0 0}
Източник: kaldata.com

СПОДЕЛИ СТАТИЯТА


Промоции

КОМЕНТАРИ
НАПИШИ КОМЕНТАР