<?xml version="1.0" encoding="utf-8" ?><rss version="2.0" xmlns:tt="http://teletype.in/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:media="http://search.yahoo.com/mrss/"><channel><title>Sovka Ivanov</title><generator>teletype.in</generator><description><![CDATA[Sovka Ivanov]]></description><image><url>https://img1.teletype.in/files/4e/cd/4ecd6f31-4a46-496f-8274-23cdfefd7dc3.png</url><title>Sovka Ivanov</title><link>https://teletype.in/@mrhuempolbu</link></image><link>https://teletype.in/@mrhuempolbu?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=mrhuempolbu</link><atom:link rel="self" type="application/rss+xml" href="https://teletype.in/rss/mrhuempolbu?offset=0"></atom:link><atom:link rel="next" type="application/rss+xml" href="https://teletype.in/rss/mrhuempolbu?offset=10"></atom:link><atom:link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></atom:link><pubDate>Sat, 03 Oct 2026 20:27:08 GMT</pubDate><lastBuildDate>Sat, 03 Oct 2026 20:27:08 GMT</lastBuildDate><item><guid isPermaLink="true">https://teletype.in/@mrhuempolbu/MkB2O0Hiteb</guid><link>https://teletype.in/@mrhuempolbu/MkB2O0Hiteb?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=mrhuempolbu</link><comments>https://teletype.in/@mrhuempolbu/MkB2O0Hiteb?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=mrhuempolbu#comments</comments><dc:creator>mrhuempolbu</dc:creator><title>Баланс билдов.</title><pubDate>Sun, 23 Feb 2025 08:10:24 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/16/d6/16d6aa5d-06ce-4171-a980-660ffea9d277.png"></media:content><description><![CDATA[<img src="https://img2.teletype.in/files/54/d2/54d25a48-1456-4422-bca8-4a1447c0ae26.png"></img>В какой-то игрульке у нас были персонажи со статами. На входе у игрока есть всего 4 параметра, по которым ему нужно каким-то образом распределить ачьки: сила ловкость и хуёвкость. На выходе же было больше десяти разных характеристик, которые аффкетятся этим распределением — там всякая меткость, скорость, размер бицухи и прочее. Идея была в том, что бы при радикальном распределении всех ачьков в один параметр характеристики персонажа получались сосунковыми, а при равномерном размазывании поинтов билд персонажа получался хорошим и крепким. Опционально было б круто ещё сделать какую-нибудь секретную пропорцию прокачки, при которой билд получается имбовым, но которую можно нащупать только методом градиентного спуска по пробам и ошибкам...]]></description><content:encoded><![CDATA[
  <h2 id="IguZ">Техническая часть.</h2>
  <p id="Lhvq">В какой-то игрульке у нас были персонажи со статами. На входе у игрока есть всего 4 параметра, по которым ему нужно каким-то образом распределить ачьки: сила ловкость и хуёвкость. На выходе же было больше десяти разных характеристик, которые аффектятся этим распределением — там всякая меткость, скорость, размер бицухи и прочее. Идея была в том, что бы при радикальном распределении всех очков в один параметр характеристики персонажа получались сосунковыми, а при равномерном размазывании поинтов билд персонажа получался хорошим и крепким. Опционально было б круто ещё сделать какую-нибудь секретную пропорцию прокачки, при которой билд получается имбовым, но которую можно нащупать только методом градиентного спуска по пробам и ошибкам. И последнее важное требование: опорные распределения должен задать геймдизайнер. Пример внизу, зелёное заполняет геймдиз на своё усмотрение, белое должен расчитывать мой инструмент.</p>
  <figure id="YzFl" class="m_original">
    <img src="https://img2.teletype.in/files/54/d2/54d25a48-1456-4422-bca8-4a1447c0ae26.png" width="851" />
    <figcaption>Ярко зелёным опорные распределения, мутно зелёным опорные билды при этих распределениях. </figcaption>
  </figure>
  <p id="lpch">Сначала мы чего-то мыкались да пыкались, пробовали да тестили, и всё получалось неустойчиво со всякими сраными побочками. Характеристики уходили в отрицательные значения, небольшое изменение входа приводило к большому изменению выхода и т.д. Из неудачных попыток я помню только линейную регрессию, остальные нерабочие варианты благополучно забыл.  В некоторый момент мы с пацанами додумались сделать визуальную модельку такой системы. Увидев это визуально, я воскликнул: «<em>Ебать меня ржавым якорем! Да это же барицентрическая залупа!</em>» И в тот же день задачка была успешно закрыта, реализация заняла несколько часов. Матчасть и вовсе несколько минут, львиная возня произошла с API гугл-табличек. </p>
  <figure id="61yO" class="m_column">
    <img src="https://img1.teletype.in/files/cf/5d/cf5d8f3b-bc00-4562-b1ab-89fda100f90e.png" width="1271" />
    <figcaption>Чёрным опорные билды, красным искомый билд.</figcaption>
  </figure>
  <p id="M0WO">Игорь распределил свои поинты, игре нужно найти три ближайших опорных распределения. Получился локальный барицентрический базис. Далее в этом базисе нужно узнать координаты игорьковского билда — это будут барицентрические веса. И далее эти веса умножить на соответствующие им статы и сложить. Если ни хера не понятно, то вот так понятно: </p>
  <ol id="fZXQ">
    <li id="obSE">Найти ближайшие опоры.</li>
    <li id="JZR4">Проинтерполироваться между ними.</li>
  </ol>
  <p id="eDXx">Корокто про возню с API гугл-табличек:</p>
  <figure id="iqZb" class="m_original">
    <img src="https://img3.teletype.in/files/61/f7/61f7b1b9-6ae1-458d-ba33-a9ee4b0bf631.png" width="468" />
  </figure>
  <h2 id="vtVd">Гуманитарная часть.</h2>
  <p id="O6vB">Это был первый раз, когда я делал математичное <strong>не CG</strong>. В будущем оказалось, что не последний, ещё пару раз нужно было выдумывать какие-то кастомные геймдизные инструменты, и в основном это было интересно. На следующих геймдизных задачках я заметил одну фундаментальную разницу между прогерством и дизайнерством: инстант результат и отложенный результат. В разработке результат работы можно оценить сразу же после нажатия кнопочки плэй; в дизайне же результат видно через три дня, тридцать дней, девяносто дней, в общем через много нажатий кнопочки плэй. И как следствие, дебаг разработки суть одно прямолинейное рассуждение, дебаг дизайна — какой-то ебучий бэк пропагейшен. </p>
  <p id="GxVH">От этой системы прокачки отказались в пользу я хз чего, я даже не знал, для какой это игры задумывалось. Да и мне оно было собственно до пизды.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@mrhuempolbu/LsJ4vEIu87z</guid><link>https://teletype.in/@mrhuempolbu/LsJ4vEIu87z?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=mrhuempolbu</link><comments>https://teletype.in/@mrhuempolbu/LsJ4vEIu87z?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=mrhuempolbu#comments</comments><dc:creator>mrhuempolbu</dc:creator><title>Расчлен на Unity.</title><pubDate>Fri, 21 Feb 2025 13:26:13 GMT</pubDate><media:content medium="image" url="https://img1.teletype.in/files/0f/e0/0fe02b28-556e-4f59-8b8c-5642faf8c6a8.png"></media:content><description><![CDATA[<img src="https://img1.teletype.in/files/cb/7b/cb7b4fde-d5da-44fa-91eb-7835ad6a5dbb.png"></img>Код не покажу, потому что это НДА и просто душно. Алгоритм расскажу, потому что это можно и круто. Всё это происходило давно, и все полезные на тот момент ссылки да ресурсы сейчас утеряны и/или неактуальны. Да и хуй с ними.]]></description><content:encoded><![CDATA[
  <h2 id="qIcM">Техническая часть.</h2>
  <p id="aLLv"><em>Код не покажу, потому что это НДА и просто душно. Алгоритм расскажу, потому что это можно и круто. Всё это происходило давно, и все полезные на тот момент ссылки да ресурсы сейчас утеряны и/или неактуальны. Да и хуй с ними.<br /></em></p>
  <figure id="i3KG" class="m_original">
    <img src="https://img1.teletype.in/files/cb/7b/cb7b4fde-d5da-44fa-91eb-7835ad6a5dbb.png" width="829" />
    <figcaption>Для заголовка.</figcaption>
  </figure>
  <p id="QBQR">Однажды мы делали пострелушки киборгов. Одной из угарных фич была расчленёнка и сочленёнка обратно. То есть какому-то терпиле (в т.ч. из своей команды) можно отстрелить нахуй голову, затем видимо войдя в кураж оторвать голову себе тоже, и водрузить на своего фрешдекапитейтед персонажа свежий трофей. <strong>БЛЯТЬ, ДА Я БЫЛ РОЖДЁН ДЛЯ ЭТОЙ ЗАДАЧИ. </strong>Беглый гугл показал, что расчлен на юнити делается легко. Там нужно-то всего лишь заготовки моделек без конечностей, и заготовки конечностей. И во время расчлена, просто нормальную модель заменять на безрукую например, а рядом спавнить оторванную руку. Но вот для обратного сочлена с такой системой требуются заготовки всех перестановок всех конечностей между всеми персонажами, что  слегка неприемлемо. И никаких других способов расчленять гуманоидов я в интернетах не нашёл, как и никаких вообще способов сочленять. Я попробовал просто детачить кость от скелета, но юнити мне сказал «<em>runtime error»</em> или что-то в этом духе, оказывается так делать нельзя. После этого <s>в маршрутке начался </s>пришлось закопаться в доку на пару дней и разбираться, как это всё говно там работает. И вот как:</p>
  <ol id="3EhV">
    <li id="BLRz">Есть иерархия костей, типа скелет. Хотя не типа ни хера, это и есть скелет. Это конкретные геймОбжекты в сцене с позишеном и ротейшеном. У них там есть параметр, какой меш на них забинден, этот параметр кайф, он мне пригодился.</li>
    <li id="UUEZ">Есть аватар. Это уже абстракция, а не конкретный объект. Можно его рассматривать как конфиг, в котором записаны имена и должности костей. Его роль — обоссанная прокладка между скелетом и аниматором. Аватар может быть произвольного или гуманоидного типа, в случае с гуманоидом у него должности костей расписаны заранее: левая рука, средняя нога и т.д. Это мне однажды вставило небольшую палочку в колёсико.</li>
    <li id="P0l3">Есть аниматор. Это компонент на руте скелета, он собирает разную инфу со всей игры: какие кнопочки сейчас нажаты, кто персонаж по жизни и т.п., инфу отправляет в контроллер, анимации отправляет в аватар. </li>
    <li id="bC3V">Есть контроллер анимаций, это обычный стейт машин, во всех движках одинаковый. Аниматор выдаёт ему разные параметры и спрашивает, что в такой ситуации делать -&gt; контроллер ему отвечает, что в такой ситуации нужно делать приседания -&gt; аниматор отправляет присед в аватара -&gt; аватар сажает кости.</li>
  </ol>
  <p id="dzPM">Отсюда я выяснил, что детачить кость просто так нельзя, потому что разрабы не готовили аватар к ситуациям, когда у скелета могут спиздить кости. Но вот конструктить на лету новый аватар с новым конфигом костей, и потом ставить его в аниматора можно. Я так и сделал. И выяснил, что гуманоидный аватар придирчив к наличию всех конечностей, на каждую руку и ногу должны быть указаны кости. Ноу проблем, я могу сделать кости, у которых параметр забинденного меша будет пустым. А если и кости будут придирчивы к наличию меша, могу сделать пустой меш, хуль тут сложного. Но к счастью кости оказались не придирчивыми. И вот, после того, как новый аватар с пустой конечностью засунут в аниматора, старый аватар автоматически уничтожается сборщиком мусора, и в сцене остаются кости оторванной конечности, которые не указаны ни в одном аватаре, и следовательно их можно доставать из иерархии скелета и отправлять в свободный регдолл. И расчлен работает с кайфом. Вот первый удачный тест.</p>
  <figure id="F1uT" class="m_column">
    <iframe src="https://www.youtube.com/embed/a2ZRTwjU_qM?autoplay=0&loop=0&mute=0"></iframe>
  </figure>
  <p id="XIfo">Далее был неожиданный и приятный момент: сочлен задействует все те же операции, просто в обратном порядке, так что его разработка прошла уже на изичах, с красивыми виражами вокруг всех ранее отпизженных моей головой граблей. На всякий случай полный порядок для сочленения: кости с оторванной конечностью засунуть в иерархию скелета -&gt; собрать новый аватар с учётом этой новой конечности -&gt; поставить аватар в аниматора. Вот последний удачный тест:</p>
  <figure id="veow" class="m_column">
    <iframe src="https://www.youtube.com/embed/SRHllxZEMN8?autoplay=0&loop=0&mute=0"></iframe>
  </figure>
  <h2 id="2bCS">Гуманитарная часть.</h2>
  <p id="gNHe">В техчасти всё описано как будто бы раз два и готово. Но на деле это оказался почти месяц разработки. Юнити вставлял очень много опущенных палок в колёса, и единственный, кто мне как-то помогал с этими палками разбираться — документация юнити. Как и в случае с декалями, никаких подобных разработок именно на юнити я в интернетах не нашёл, поэтому во всём пришлось разобраться самому методом проб и ошибок. <br />Игрульку выпустили в открытую бету, собрали фидбек, и свернули разработку. И тут мне было немножечко обидно, потому что я во всякий драйв и трэш люблю играть, и эту игру я бы хотел помацать в финальной версии со всеми её кровавыми угарами.<br />Ещё мне в этом проекте доверили сделать немного рига на киборгов, чтоб они от попаданий дёргались физкорректно, чтоб отдача от выстрелов была и ещё чот там такое. Ниже пара мемов с этого этапа работы. Вообще в процессе разработки было много дикого ора, угара, смехуёчков и веселья. И пара кранчей была, которая полностью того стоила, ящетаю.</p>
  <figure id="fVb3" class="m_column">
    <img src="https://img4.teletype.in/files/f8/43/f843e94e-29b3-4900-ae13-e2d766b8e0a8.jpeg" width="482" />
    <figcaption>Это жожо референс?</figcaption>
  </figure>
  <figure id="gNgn" class="m_column">
    <img src="https://img2.teletype.in/files/de/d7/ded7917d-51fa-472a-aacf-6859c61e6d3e.jpeg" width="526" />
  </figure>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@mrhuempolbu/9TjV7jmrlht</guid><link>https://teletype.in/@mrhuempolbu/9TjV7jmrlht?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=mrhuempolbu</link><comments>https://teletype.in/@mrhuempolbu/9TjV7jmrlht?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=mrhuempolbu#comments</comments><dc:creator>mrhuempolbu</dc:creator><title>Запечёный GI на webGL.</title><pubDate>Fri, 21 Feb 2025 07:34:05 GMT</pubDate><media:content medium="image" url="https://img3.teletype.in/files/2a/da/2adaee11-0a2e-42fb-b20c-9106bfef8b42.png"></media:content><description><![CDATA[<img src="https://img4.teletype.in/files/f9/4a/f94a9046-9e94-4cdb-99d2-92f7e3e8af22.jpeg"></img>Код не покажу, потому что это НДА и просто душно. Алгоритм расскажу, потому что это можно и круто. Всё это происходило давно, и все полезные на тот момент ссылки да ресурсы сейчас утеряны и/или неактуальны. Да и хуй с ними.]]></description><content:encoded><![CDATA[
  <h2 id="qIcM">Техническая часть.</h2>
  <p id="aLLv"><em>Код не покажу, потому что это НДА и просто душно. Алгоритм расскажу, потому что это можно и круто. Всё это происходило давно, и все полезные на тот момент ссылки да ресурсы сейчас утеряны и/или неактуальны. Да и хуй с ними.</em></p>
  <figure id="jpNC" class="m_column">
    <img src="https://img4.teletype.in/files/f9/4a/f94a9046-9e94-4cdb-99d2-92f7e3e8af22.jpeg" width="1280" />
    <figcaption>Ноль источников света.</figcaption>
  </figure>
  <figure id="5S8G" class="m_column">
    <img src="https://img4.teletype.in/files/31/48/3148a2a3-d5c4-4bd9-b273-997f2ed31ec1.jpeg" width="1280" />
    <figcaption>ДжиАй онли. </figcaption>
  </figure>
  <p id="Srq5">Делали какую-то пострелушку на браузерном движке Playcanvas. По какой-то причине нам захотелось добавить туда global illumination, который предварительно красиво запечь где-нибудь там в гудини например. Чтоб персонаж бегал по левелу, и угарно освещался этим левелом. Но лайтпроб-то в плейканвасе нету. Значит придётся их своими руками сделать. На мне повисла работа по движку, на другом серьёзном пацане работа по гудини. Идея запекания проста: разбить пространство на грид точек, в каждой точке посчитать освещённость (цвет, интенсивность опционально), все эти значения упаковать в жсон и отдать мне. Идея лайтпроб тоже проста: засунуть этот жсон в шейдер, и шейдером разобраться с какого раена конкретная точка на геометрии, которую сейчас надо осветить, кто её ближайшие соседи из запечённого грида, и  проинтерполироваться между этими соседями. Реализация оказалась тоже проста — всё как задумали, так и сделали. По части запекания в гудиче я хз какие проблемы возникали, это были не мои проблемы. У меня же возникла беда с суванием жсона в шейдер, ибо webGL того времени не поддерживал никаких буферов, и никаким удобным образом массив кастомных данных в GPU не передать. Но есть неудобный способ, который я уже применял в декалях — закодировать всю эту парашу в текстуру, и отправлять в видеокарту текстуру. Благо наши так называемые <em>кастомные</em> данные — это RGB, так что и кодировать даже ничего не пришлось, взял цвет точки, положил в цвет текселя, хуль тут сложного. Ну и вот, теперь у меня есть текстура, в каждом пикселе которой находится значение освещённости в какой-нибудь точке сцены. Эту текстуру я могу сувать в шейдер. Шейдер написал без приключений — там просто определение соседей да интерполяция между ними, ничего интересного. А потом снова нюанс: этот фейк-джиай должен быть встроен во все материалы сцены. Чтобы художники там понастраивали материальчики, игру включили, а мой GI опа и работает сам собой. И такую возможность встраивания своего кода в код материала плэйканвас предоставляет. Молодец какой. Там это называется shader chunks. Суть в том, что шейдеры компилятся при запуске игры, а не в едиторе. В едиторе же они хранятся текстом, просто открытым голым кодом валяются, а значит промеж этого заводского кода можно сувать свой кастомный код. И при запуске компилиться будет уже заводской шейдер со встроенными кусками моего. Я свой шейдер и положил во все материалы в чанк люминанса. А потом чтобы художники могли новые материалы добавлять, и меня не дёргать мол включи ну включи джиай, я бахнул скрипт, который при запуске ещё до компиляции шейдеров все материалы собирает, и суёт в них мой шейдер.</p>
  <p id="yFlX"></p>
  <h2 id="ghxq">Гуманитарная часть.</h2>
  <p id="mDcB">Давным-давно я щупал движок юниджайн, кажется это был ещё 2014. Там я увидел лайтпробы и охуел как вкопанный. Это казалось обоссаным чудом, что глобал иллюминейшен возможен в риалтайме хоть в каком-то виде. Я тогда думал, что это какие-то надмозги придумали и даже не пытался там что-то изучить или поприкидывать, как это могли сделать; просто подумал «не для моих мозгов», пустил дегенеративную слюнку и забил хуйца. И вот спустя шесть лет мне поставили задачку бахнуть этот иллюминейшен в браузере. И мне не понадобилось даже ничего гуглить, идея как это сделать пришла сразу же, я сразу эту идею реализовал, и всё прошло гладко, легко и быстро. На протяжении всего дня разработки я не воспользовался гуглом ни разу. Задачка казалась пугающей издалека, но вблизи на практике выяснилось, что а разговоров-то было.</p>

]]></content:encoded></item><item><guid isPermaLink="true">https://teletype.in/@mrhuempolbu/sWUvt_vDQnQ</guid><link>https://teletype.in/@mrhuempolbu/sWUvt_vDQnQ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=mrhuempolbu</link><comments>https://teletype.in/@mrhuempolbu/sWUvt_vDQnQ?utm_source=teletype&amp;utm_medium=feed_rss&amp;utm_campaign=mrhuempolbu#comments</comments><dc:creator>mrhuempolbu</dc:creator><title>Декали на webGL.</title><pubDate>Thu, 20 Feb 2025 08:30:55 GMT</pubDate><media:content medium="image" url="https://img2.teletype.in/files/db/c3/dbc35ef0-6c22-4f5a-aa0b-f90d8bfec043.png"></media:content><description><![CDATA[<img src="https://img4.teletype.in/files/7d/67/7d67d7f8-e1d4-4597-a0cb-3c82bd650c94.png"></img>Код не покажу, потому что это НДА и просто душно. Алгоритм расскажу, потому что это можно и круто. Всё это происходило давно, и все полезные на тот момент ссылки да ресурсы сейчас утеряны и/или неактуальны. Да и хуй с ними.]]></description><content:encoded><![CDATA[
  <h2 id="qIcM">Техническая часть.</h2>
  <p id="aLLv"><em>Код не покажу, потому что это НДА и просто душно. Алгоритм расскажу, потому что это можно и круто. Всё это происходило давно, и все полезные на тот момент ссылки да ресурсы сейчас утеряны и/или неактуальны. Да и хуй с ними.</em></p>
  <p id="IfJy">Что такое декали, если по какой-то причине твоя карьера прошла мимо них:</p>
  <figure id="XXaE" class="m_original">
    <img src="https://img4.teletype.in/files/7d/67/7d67d7f8-e1d4-4597-a0cb-3c82bd650c94.png" width="1801" />
  </figure>
  <p id="Pvvu">Мне нужно было их бахнуть на браузерном игровом движке Playcanvas. Требований было немного, вот они все трое:</p>
  <ul id="soqx">
    <li id="Tr2m">Декали должны быть со своим материалом, своими параметрами спекуляра с говном.</li>
    <li id="Jyal">Они должны спавниться в рантайме, то есть охуенно быстро.</li>
    <li id="xTpd">Их может наспавниться очень много, так что количество декалек должно очень слабо влиять на перформанс.</li>
  </ul>
  <p id="fpD2"><br />И первым применением по плану должны были стать брызги крови на стенах, на полу, на любой геометрии, РАЗМАЗАТЬ ЭТО ДЕРЬМО ПО ВСЕЙ СЦЕНЕ. И думая о кровище, я от себя добавил ещё немного требований:</p>
  <ul id="LJEV">
    <li id="WEdL">Расстояние от источника брызг до поверхности должно влиять на дисперсию.</li>
    <li id="foDD">Форма брызгульки должна зависеть от угла между направлением брызг и поверхностью.</li>
    <li id="D8cQ">Каждая брызга уникальна по форме, никаких подготовленных текстур, чисто генератив.</li>
  </ul>
  <p id="LTNM">Позже оказалось, что первые два требования — это одно и то же требование в двух разных интерпретациях, это круто.</p>
  <p id="O5BD">Все перестрелки между игорьками происходят на стороне CPU, то есть высчитывать направление и позишен декали придётся именно там. А рендерить придётся на GPU.  Другой поганый момент — на GPU мне не сделать какую-то угарную структуру данных, в которую можно было бы на расслабоне складывать и хранить прилетающие из CPU декальки, которые при рендере доставать и юзать не снимая свитер. Значит удобно складывать и хранить эти декали придётся тоже на стороне CPU. Учитывая требования выше, мне нужна структура данных, у которой максимально быстрая вставка нового элемента, адекватно быстрый поиск элемента и максимально сильное похуй всё остальное. Спецфичи, которые могут помочь — у декалей три координаты, значит моя структурка может быть трёхмерной. Сразу же в голову пришло ЕБЕЩЕЕ ОКТОДЕРЕВО, оно ведь будто бы рождено для этой задачи, мэтчинг по требованиям сто из ста. И я его сделал. Вот как это говно у меня работало (ячейки октодерева во всём этом длинночтене я буду называть вокселями).</p>
  <p id="jEZw"><strong>1. ИНИШИАЛ СОСТОЯНИЕ.</strong><br />Существует структурка декали, в ней лежит матрица и какая-то кастомная инфа, например таймстамп или цвет или что угодно.<br />Существует тупа массив декалей. При ините естеесн пустой. <br />Существует структурка вокселя, в ней лежат восемь интеджеров (ссылки на декали в предыдущем массиве либо на другие воксели в этом же массиве); чекбокс subdivided; какая-то техническая инфа, которая я уже и не помню для нахуя.<br />Существует тупа массив вокселей. Оба массива нужны отдельно для отправки всех этих данных на GPU, потому что октодерево туда не отправить.<br />И собсна само октодерево: в инишиал состояни это просто один большой воксель размером с весь левел.</p>
  <p id="KyKS"><strong>2. СПАВН.</strong><br />Спавнится первая декаль, вторая и вплоть до восьмой — массив декалей пополняется, в большом вокселе восемь сцылок заполняются. И тут спавнится предательская девятая декаль. В массив она конечно на изи попадает, но в вокселе для неё места нету, все ссылки заняты. И этот кедр просто делится на восемь вокселей поменьше. Они попадают в массив вокселей. Те восемь декалей, которые в большом папе, распихиваются по его дочкам, папа-воксель ставит себе чекбокс subdivided, и ссылки на декали заменяет ссылками на дочек.</p>
  <figure id="YYBD" class="m_column">
    <img src="https://img3.teletype.in/files/67/55/6755490d-90e9-4e19-a162-fc9e386d554a.png" width="1705" />
    <figcaption>Ни хуя не понятно, но очень интересно. Слева до деления вокселя, справа после.</figcaption>
  </figure>
  <p id="X4BC"><strong>3. ПОИСК.<br /></strong>Позишен свежей декальки поступает в первый большой папа-воксель. Если этот воксель уже разбит, то он оценивает, с какого раена свежая декаль, и кому из дочек её отправить, и отправляет. Доча-воксель, принявшая эту декаль, поступает с ней точно так же. И так до тех пор, пока декаль не дойдёт до вокселя, который ещё не разбит на дочек, и в котором есть для неё место.</p>
  <p id="H0hh"><strong>4. ПРОФИТ.<br /></strong>Казалось бы ни хера себе тут работы, компуктер перегреется. Хотя если ты шаришь за <em>O(n)</em>, то тебе не казалось бы. Тем не менее. На тестах декали вставляются не то что с лагом, а с ускорением нахуй. Фпс вверх подскакивает, когда декаль спавнится. Шучу конечно, фпс просто не дёргается, никакого лага нету, всё работает максимально с кайфом. Октодерево аппрувед.</p>
  <blockquote id="Nkvr">Маленькай момент с максимальной глубиной дерева, доколе оно может делиться. Тут изи посчитать, на карте максимально может бегать <em>x</em> челиков, в каждого можо сделать максимум <em>y</em> попаданий до разлома кабины. Пусть карта отмывается от крови раз в <em>z</em> каток. Итого максимально может заспавниться <em>x*y*z</em> декалей. Первые два множителя это данность, константа, факт, принимаем это. Третий множитель на тестах регулируем так, чтобы и крови копилось нормально, и переполнений дерева не возникало. Но вообще для деления дерева до глубины всего лишь пять уже требуется восемь в пятой степени успешных ранений игорьков — это 32 тысячи выстрелов, тридцать две тысячи нажатий ЛКМ при условии что все ниибаца меткие. Поэтому эта тяга с дроблением дерева в бесконечность меня не кошмарила. Алсо в воксели можно записывать их поколение, и просто его ограничить, но я кажется забил хер либо забыл.</blockquote>
  <p id="WleO">Теперь нужно передать массив декалек на GPU и начатьь уже рендорить. Не так быстро, молодой человек. В webGL на тот момент не было никаких буферов, webGPU не существовал даже в открытой бете, прямого пути переправить сраный массив данных из проца в видяху на вебе просто нету. Но есть косой путь — текстуры. Значит надо просто задекодить объекты декалек в наборы пикселей, а на стороне шейдера раздекодить обратно, хуль тут сложного. Тут я особо ничего не делал, собрал пару кодов со стакОверфлоу, они по какой-то причине не работали, починил, бахнул пивасика, посмотрел серик, в то время «дом дракона» только начинался. В общем трансфер данных налажен, остался рендер. И раз уж все брызги крови будут одним и тем же материалом — почему бы их все не рендерить за один дроколл. Просто взять шейдер крови, накинуть сразу на всю геометрию в сцене, а декали использовать как маску для этого шейдера. И как раз количество декалей не будет влиять не перфоманс вообще, и все требования получаются выполнены. Так и сделал, весь левел со старта облит кровью, просто с альфой. Когда кто-то cum blood — декаль затирает маску, и в этом месте материал крови становится непрозрачный.</p>
  <p id="8ncy">Теперь про шейдер. В шейдере по умолчанию всегда можно добыть глобальный позишен обрабатываемого пикселя, так уж оно устроено. Так же там есть массив вокселей, который прилетел с проца, и нулевой в этои массиве — папа всех вокселей. Зная всё это, шейдер спрашивает у папы, есть ли у того доченьки. Если есть, шейдер по позишену сам определяет к кому из дочек обратиться, и обращается. И так до тех пор, пока не найдёт ту, что не разделена. И шейдер пройдётся по всем декалям в ней, и каждой из них подотрёт свою альфу. Здесь выяснился вот такой момент:</p>
  <figure id="ePLk" class="m_column">
    <img src="https://img2.teletype.in/files/1e/39/1e39c4f8-1575-479f-8c8b-9fc06de72a9a.png" width="1143" />
  </figure>
  <figure id="wNDu" class="m_column">
    <img src="https://img3.teletype.in/files/e1/35/e13506b4-5544-4c00-892b-2bc14140f37d.png" width="663" />
    <figcaption>Чёрным воксели, красным декаль, зелёным рендер декали.</figcaption>
  </figure>
  <p id="Av3g">Центр декали в левом вокселе, там шейдер её находит и рендерит. В правом вокселе шейдер её не находит и не рендерит. Значит вставка декалей в воксели должна происходить по другому принципу. Не в тот воксель, внутри которого находится её центр, а во все воксели, с которыми она интерсектится. Внёс эту правку, на перфоманс не повлияло, всё хорошо. Теперь шейдер всегда понимает в каком пикселе сколько декалей находится.</p>
  <p id="xaML">Ещё нужен мапинг декали на поверхность. Тут инфы в интернете полно, отдельно разжёвывать не буду, взял да замапил. Но в этот дефолтный мапинг я добавил небольшой нюанс — перспективу брызгульки. То есть баундБокс декали расширяется по оси <strong>Z</strong>, и похож на фрустум камеры. Это как раз для дисперсии с расстоянием. И неожиданно это же делает брызги красивыми, когда они проходят вдоль стены например. То есть два моих выдуманных требования я убил одним зайцем. </p>
  <figure id="2u3t" class="m_column">
    <img src="https://img3.teletype.in/files/a3/bf/a3bf5c90-ceb7-41b0-9a5f-7a9e8b21e1b1.png" width="2332" />
  </figure>
  <p id="XHAT">Ну и последнее — брызговая маска. Тупо нойз. Обычный сука дженерик нойз, без перлина и без каких-либо выебонов вообще. Яркость нойза уменьшается с расстоянием от центра декали, таким образом капелек к краям становится всё меньше. И с художественной частью кровищи, то есть с обычной и заурядной частью шейдера, я работать особо не стал, тут есть люди, которые сделают это быстрее и красивее меня. А мне требовалось обобщить полученное решение, чтобы брызги крови были в один клик заменяемы на что угодно — лужи, пыль, следы и т.д. Тут уже ничего интересного, это полурутинная работа.</p>
  <figure id="yJhO" class="m_column">
    <iframe src="https://www.youtube.com/embed/hDOxHVqArec?autoplay=0&loop=0&mute=0"></iframe>
    <figcaption>декали в браузере 60 фпс жесть смотреть.</figcaption>
  </figure>
  <h2 id="p9KS">Гуманитарная часть.</h2>
  <p id="e4Y4">На момент, когда мне эту задачку поставили, я не знал о внутренности декалей ровно ничего. Знал только, что такая технология существует, юзал декальки когда-то давно в анриле. Полез гуглить как там в плейканвасе с декалями вопрос обстоит. Не нашёл ничего вообще, про это были вопросы на форуме, вопросы без ответов, вопросы с ответвами от разрабов, дескать функционала такого у нас нету и не предвидится, сасайте палка. После я полез гуглить как сделать декали на openGL, нашёл полезную инфу про мапинг декалей, какой-то видос с не очень полезной, но крутой инфой от графоноинженера какой-то трипл-инди хуйни. Но не нашёл ничего, что могло бы мне помочь. Зато начерпавшись вот этой всей рандомной хуерги со всего интернета по запросу «<em>decals openGL</em>», решение по-тихонечку начало формироваться как будто бы само собой. Я просто сижу, в носу ковыряю, ничего не делаю, а идея приходит. Ну не кайф ли. Кайф. Потом правда приходится эту идею реализовавыть, что в общем-то тоже кайф. А иногда в процессе реализации осознаётся, что идея не рабочая, и нужно ещё поковырять в носу, что снова кайф. Хоспаде, да какой этап разработки не возьми — всё кайф. <br />Игра, для которой это всё делалось в итоге переехала на юнити, и эти декали канули в хер. Никаких эмоций у меня по этому поводу не возникало, я свой балдёж высосал из разработки до дна.</p>

]]></content:encoded></item></channel></rss>