- PVSM.RU - https://www.pvsm.ru -
Демосцена — это о создании классных штук, которые работают в реальном времени (как бы «крутятся в вашем компьютере»). Их называют демки. Некоторые из них по-настоящему маленькие, скажем, 64k или меньше — такие называются интро. Название происходит от рекламирования или представления взломанных программ (crack intro). Итак, интро — это просто маленькая демка.
Я заметил, что многим интересны произведения демосцены, но они не имеют понятия, как в реальности делаются демки. В этой статье — мозговой дамп и посмертное вскрытие нашего свежего интро Guberniya. Надеюсь, будет интересно и новичкам, и опытным ветеранам. Статья затрагивает практически все техники, которые используются в демках, и должна дать хорошее представление о том, как их делать. В этой статье я буду называть людей по никам, потому что именно так принято на сцене.
Бинарник под Windows: guberniya_final.zip (61.8 kB) [1] (немного ломается на картах AMD)
Это 64k интро, выпущенное на демопати Revision 2017 [2]. Некоторые цифры:
Демки обычно выпускаются на демопати, где зрители смотрят их и голосуют за победителя. Выпуск для демопати даёт хорошую мотивацию, потому что у вас твёрдый дедлайн и страстная аудитория. В нашем случае это была Revision 2017 [2], большая демопати, которая традиционно проходит в пасхальные выходные. Можете глянуть несколько фотографий [5], чтобы получить представление о мероприятии.
Количество коммитов в неделю. Самый большой всплеск — это мы срочно хакаем прямо перед дедлайном. Два последних столбца — изменения для финальной версии, после демопати
Мы начали работать над демкой в начале января и выпустили её на Пасху в апреле во время мероприятия. Можете посмотреть запись всего соревнования [6], если желаете :)
Наша команда состояла из шести человек: cce (это я), varko [7], noby [8], branch [9], msqrt и goatman.
Песня была готова на довольно ранней стадии, так что я попробовал нарисовать что-то по её мотивам. Было ясно, что нам нужно нечто большое и кинематографическое с запоминающимися частями.
Первые визуальные идеи вращались вокруг проводов и их использования. Мне действительно нравятся работы Виктора Антонова, так что первые наброски во многом скопированы из Half-Life 2:
Первые наброски башен цитадели и амбициозных человеческих персонажей. Полный размер [10].
Концептуальная работа Виктора Антонова для Half-Life 2: Raising the Bar
Сходства вполне очевидны. В ландшафтных сценах я также пытался передать настроение Eldion Passageway [11] Энтони Шимеса.
Ландшафт создан под вдохновением этого славного видео об Исландии [12], а также «Койяанискаци», наверное. У меня имелись большие планы насчёт истории, изображённой на раскадровке:
Эта раскадровка отличается от окончательной версии интро. Например, брутальную архитектуру вырезали. Полная раскадровка [13].
Если я бы делал заново, то ограничился бы просто парой фотографий, которые задают настроение. Так меньше работы и больше пространства для воображения. Но по крайней мере рисование помогло мне упорядочить мысли.
Космический корабль спроектировал noby [8]. Это сочетание многочисленных фракталов Мандельброта, пересекающихся с геометрическими примитивами. Дизайн корабля остался немного незавершённым, но нам показалось, что лучше не трогать его в финальной версии.
Космический корабль представляет собой рейкастинг поля расстояний, как и всё остальное.
У нас был ещё один шейдер корабля, который не вошёл в интро. Сейчас я смотрю на дизайн, он очень крут, и очень жаль, что для него не нашлось места.
Дизайн космического корабля от branch. Полный размер [14].
Мы начали с кодовой базы нашего старого интро Pheromone [15] (YouTube [16]). Там была базовая функциональность кадрирования и библиотека стандартных функций OpenGL вместе с утилитой файловой системы, которая паковала файлы из директории с данными в исполняемый файл, используя bin2h
.
Для компиляции проекта мы использовали Visual Studio 2013, потому что он не скомпилировался в VS2015. Наша замена стандартной библиотеки не очень хорошо работала с обновлённым компилятором и выдавала забавные ошибки вроде таких:
Visual Studio 2015 не ужился с нашей кодовой базой
По какой-то причине мы всё равно застряли на VS2015 как редакторе и просто скомпилировали проект, используя инструментарий платформы v120.
Большая часть моей работы с демкой выглядело так: шейдеры открыты в одном окне, а конечный результат с консольной выдачей — в других. Полный размер [17].
Мы сделали простой глобальный перехват нажатий клавиш, который перезагружал все шейдеры, если обнаруживал комбинацию CTRL+S:
// Listen to CTRL+S.
if (GetAsyncKeyState(VK_CONTROL) && GetAsyncKeyState('S'))
{
// Wait for a while to let the file system finish the file write.
if (system_get_millis() - last_load > 200) {
Sleep(100);
reloadShaders();
}
last_load = system_get_millis();
}
Это работало по-настоящему классно, и редактирование шейдеров в реальном времени стало гораздо интереснее. Не нужны какие-то перехваты событий файловой системы и тому подобное.
Для анимации и постановки мы использовали Ground Control [18], форк GNU Rocket [19]. Rocket — это программа для редактирования анимационных кривых, она подключается к демке через сокет TCP. Опорные кадры отправляются по запросу демки. Это очень удобно, потому что вы можете редактировать и перекомпилировать демку, не закрывая редактор и не рискуя потерять позицию синхронизации. Для окончательной версии опорные кадры экспортируются в бинарный формат. Впрочем, там есть некоторые досадные ограничения [20].
Изменять точку зрения мышкой и клавиатурой очень удобно, чтобы выбирать углы камеры. Даже простой GUI сильно помогает, когда мелочи имеют значение.
В отличие от некоторых [21], у нас не было инструмента для демок, так что пришлось создавать его по мере работы. Великолепная библиотека dear imgui [3] позволяет легко добавлять функции по мере надобности.
Например, нужно добавить несколько ползунков для управления параметрами цветности — достаточно всего лишь внести эти строчки в цикл рендеринга (не в отдельный код GUI).
imgui::Begin("Postprocessing");
imgui::SliderFloat("Bloom blur", &postproc_bloom_blur_steps, 1, 5);
imgui::SliderFloat("Luminance", &postproc_luminance, 0.0, 1.0, "%.3f", 1.0);
imgui::SliderFloat("Threshold", &postproc_threshold, 0.0, 1.0, "%.3f", 3.0);
imgui::End();
Конечный результат:
Эти ползунки было легко добавить.
Позицию камеры можно сохранить в файл .cpp
, нажав F6
, так что после следующей компиляции она будет в демке. Это устраняет необходимость отдельного формата данных и соответствующего кода сериализации, но такое решение тоже может оказаться довольно неаккуратным.
Главное для минимизации бинарника — выбросить стандартную библиотеку и сжать скомпилированный бинарник. В качестве базы для нашей собственной реализации библиотеки мы использовали Tiny C Runtime Library [22] от Mike_V.
Сжатием бинарников занимается kkrunchy [4] — инструмент, сделанный именно для этой цели. Он работает с отдельными исполняемыми файлами, так что вы можете написать свою демку на C++, Rust, Object Pascal или чём угодно ещё. Если честно, размер для нас не был особой проблемой. Мы не хранили много бинарных данных вроде изображений, так что было пространство для манёвра. Даже не пришлось удалять комментарии из шейдеров!
Код с плавающей запятой доставил некоторую головную боль, осуществляя вызовы к функциям несуществующей стандартной библиотеки. Большинство из них удалось устранить, отключив векторизацию SSE ключом компилятора /arch:IA32
и удалив вызовы к ftol
с помощью флага /QIfst
, который генерирует код, не сохраняющий флаги FPU для режима усечения. Это не проблема, потому что вы можете установить режим усечения с плавающей запятой в начале своей программы с помощью такого кода от Питера Шоффхаузера [23]:
// set rounding mode to truncate
// from http://www.musicdsp.org/showone.php?id=246
static short control_word;
static short control_word2;
inline void SetFloatingPointRoundingToTruncate()
{
__asm
{
fstcw control_word // store fpu control word
mov dx, word ptr [control_word]
or dx, 0x0C00 // rounding: truncate
mov control_word2, dx
fldcw control_word2 // load modfied control word
}
}
Можете почитать больше о подобных вещах на benshoof.org [24].
Вызов pow
по-прежнему генерирует вызов к внутренней функции __CIpow
, которая не существует. Я никак не мог сам выяснить её сигнатуру, но нашёл реализацию в ntdll.dll из Wine [25] — стало ясно, что она ожидает в регистрах два числа двойной точности. После этого стало возможным сделать враппер, который вызывает нашу собственную реализацию pow
:
double __cdecl _CIpow(void) {
// Load the values from registers to local variables.
double b, p;
__asm {
fstp qword ptr p
fstp qword ptr b
}
// Implementation: http://www.mindspring.com/~pfilandr/C/fs_math/fs_math.c
return fs_pow(b, p);
}
Если знаете лучший способ, как бороться с этим, пожалуйста, сообщите.
Если не можете рассчитывать на SDL или нечто подобное, то приходится использовать чистый WinAPI для необходимых операций по выводу окна на экран. Если возникли проблемы, вот что может помочь:
Обратите внимание, что в последнем примере мы загружаем указатели функций только для тех функций OpenGL, которые реально используются в деле. Хорошей идеей может быть автоматизировать это. К функциям нужно обращаться вместе со строковыми идентификаторами, которые хранятся в исполняемом файле, так что чем меньше функций загружается — тем больше экономия места. Опция Whole Program Optimization [30] может убрать все неиспользуемые строковые литералы, но мы не будем её использовать из-за проблемы с memcpy [31].
Рендеринг производится, в основном, методом рейкастинга, и для удобства мы использовали библиотеку hg_sdf [32]. Иньиго Куилез [33] (с этого момента именуемый просто iq) многое написал об этой и многих других техниках. Если вы когда-нибудь посещали ShaderToy [34], то должны быть знакомы с этим.
Вдобавок, у нас была выдача рейкастера — значение буфера глубины, так что мы могли совместить знаковые поля расстояний с геометрией в растере, а также применить эффекты пост-обработки.
Мы применили стандартный шейдинг Unreal Engine 4 (вот большой pdf с описанием [35]) с капелькой GGX. Это не очень заметно, но имеет значение в основным моментах. С самого начала мы планировали сделать одинаковое освещение как для рейкастинга, так и для растеризированных форм. Идея была в использовании отложенного рендеринга и теневых карт, но это совершенно не получилось.
Один из первых экспериментов с наложением теневых карт. Заметьте, что обе башни и провода отбрасывают тень на рейкастинговую землю и также правильно пересекаются. Полный размер [36].
Невероятно сложно правильно провести рендеринг больших территорий с теневыми картами из-за дико скачущего соотношения экрана-к-теневой карте-текселю и других проблем с точностью. У меня также не было желания начинать эксперименты с каскадными теневыми картами [37]. К тому же, рейкастинг одной и той же сцены с разных углов зрения реально медленный. Так что мы просто решили отдать на слом всю систему одинакового освещения. Это оказалось огромной проблемой позже, когда мы пытались соотнести освещение растеризированных проводов и рейкастинговой геометрии сцены.
Рейкастинг местности производился численным шумом [38] с аналитическими производными.1 [39]старую статью об этой технике [40] или поиграйтесь с классной сценой тропического леса на ShaderToy [41]. Карта высот ландшафта стала более реалистичной, когда msqrt реализовал экспоненциально распределённый шум [42].
Первые тесты моей собственной реализации численного шума.
Реализация местности от branch, которую решили не использовать. Не помню почему. Полный размер [43].
Эффект ландшафта рассчитывается очень медленно, потому что мы брутфорсим тени и отражения. Использование теней — это небольшой хак с тенями [44], в котором размер полутени определяется кратчайшим расстоянием, которое встретилось при обходе луча тени. Они выглядят довольно неплохо в действии [45]. Мы также попытались использовать половинчатую трассировку для ускорения эффекта, но она производила слишком много артефактов. С другой стороны, хитрости рейкастинга [46] от Mercury [47] (ещё одна демогруппа) помогли нам немного улучшить качество без потери скорости.
Рендеринг ландшафта улучшенными итерациями с фиксированной запятой (слева) по сравнению с обычным рейкастингом (справа). Обратите внимание на неприятные артефакты ряби на картинке справа.
Небо генерируется практически такими же техниками, как описано в behind elevated [48] от iq, слайд 43. Несколько простых функций вектора направления луча. Солнце выдаёт довольно большие значения в кадровый буфер (выше 100), так что это тоже добавляет некоторой цветовой естественности.
Это вид, созданный под влиянием фотографий Фан Хо [49]. Наши эффекты пост-обработки действительно позволили создать цельную сцену, хотя изначальная геометрия довольно проста.
Безобразное поле расстояния с некоторыми повторяющимися фрагментами. Полный размер [50].
Добавлено немного тумана с экспоненциальным изменением расстояния. Полный размер [51].
Провода делают сцену более интересной и реалистичной. Полный размер [52].
В окончательной версии в поле расстояния добавлено немного шума, чтобы создать впечатление кирпичных стен. Полный размер [53].
При пост-обработке добавлены цветной градиент, цветность, хроматические аберрации и блики. Полный размер [54].
Бомбардироващики B-52 — хороший пример моделирования со знаковыми полями расстояний. Они были гораздо проще на этапе разработки, но мы довели их к финальному релизу. Издали выглядят довольно убедительно:
Бомбардировщики нормально выглядят на расстоянии. Полная версия [55].
Однако это просто кучка капсул. По общему признанию, было бы легче просто смоделировать их в каком-нибудь 3D-пакете, но у нас под рукой не было какого-нибудь инструмента для редактирования полигональных сеток, так что мы выбрали более быстрый способ. Просто для справки, вот как выглядит шейдер поля расстояния: bomber_sdf.glsl [56].
Однако они на самом деле очень простые. Полный размер [57].
Первые четыре кадра анимации козла.
Анимированные персонажи — это просто упакованные 1-битные растровые изображения. При воспроизведении кадры плавно переходят от одного к другому. Материал предоставил таинственный goatman.
Козопас со своими друзьями.
Эффекты пост-обработки написал varko. Система следующая:
Блики объектива во многом следуют технике, описанной Джоном Чэпмэном [59]. С ними иногда было тяжело работать, но конечный результат доставляет.
Мы попытались эстетично использовать эффект глубины резкости. Полный размер [60].
Эффект глубины резкости (основанный на технике DICE [61]) делается в три прохода. Первый вычисляет размер кружка нерезкости для каждого пикселя, а два других прохода накладывают на них два пятна из вращающихся областей. Мы также делаем улучшение в несколько итераций (в частности, накладываем многочисленные гауссовские размытия) при необходимости. Такая реализация хорошо работала у нас и с ней было весело играться.
Эффект глубины резкости в действии. На красной картинке показан рассчитанный кружок резкости для пятна DOF.
В Rocket есть анимированный параметр pp_index
, который используется для переключения между профилями цветовой коррекции. Каждый профиль — просто разные ветки большого оператора ветвления в шейдере окончательной пост-обработки:
vec3 cl = getFinalColor();
if (u_GradeId == 1) {
cl.gb *= UV.y * 0.7;
cl = pow(cl, vec3(1.1));
} else if (u_GradeId == 2) {
cl.gb *= UV.y * 0.6;
cl.g = 0.0+0.6*smoothstep(-0.05,0.9,cl.g*2.0);
cl = 0.005+pow(cl, vec3(1.2))*1.5;
} /* etc.. */
Он очень простой, но работает достаточно хорошо.
В демке есть две моделируемые системы: провода и стая птиц. Их тоже написал varko.
Провода добавляют сцене реалистичности. Полный размер [62].
Провода рассматриваются как ряд пружин. Их моделируют на GPU с использованием вычислительных шейдеров. Мы делаем эту симуляцию во много маленьких шажков из-за нестабильности метода численного интегрирования Верле, который здесь используем. Вычислительный шейдер выдаёт также геометрию провода (ряд треугольных призм) в буфер вершин. К сожалению, по какой-то причине симуляция не работает на картах AMD.
Птицы дают ощущение масштаба.
Модель стаи состоит из 512 птиц, где первые 128 считаются лидерами. Лидеры двигаются по шаблону вихревого шума [63], а остальные следуют за ними. Думаю, что в реальной жизни птицы следуют за движениями ближайших соседей, но и такое упрощение выглядит достаточно хорошо. Стая рендерилась как GL_POINTs
, у которых модулировался размер, чтобы создать впечатление взмахов крыльев. Я думаю, такая техника рендеринга также использовалась в Half-Life 2.
Обычно музыку для 64k интро делают с помощью VST-плагина [64]: так музыканты могут использовать свои привычные инструменты для сочинения музыки. Классический пример такого подхода — V2 Synthesizer [65] от farbrausch.
Это было проблемой. Я не хотел использовать какой-то готовый синтезатор, но из предыдущих неудачных экспериментов мне было известно, что изготовление собственного виртуального инструмента потребует много работы. Помню, как мне действительно понравилось настроение демки element/gesture 61% [66], которую сделал branch с музыкальной эмбиент-темой, подготовленной в paulstretched [67]. Это натолкнуло меня на мысль реализовать такое в размере 4k или 64k.
Paulstretch — великолепный инструмент для действительно сумасшедшего растягивания музыки. Если вы о нём не слышали, то вам определённо стоит послушать, что он может сделать из звука приветствия Windows 98 [68]. Его внутренние алгоритмы описаны в этом интервью с автором [69], и он к тому же open source.
Оригинальный звук (сверху) и растянутый звук (снизу), созданный с помощью эффекта Paulstretch для Audacity. Заметьте также, как частоты размазываются по спектру (вертикальная ось).
По существу, вместе с растяжением исходного сигнала он ещё и взбалтывает его фазы в частотном пространстве, так что вместо металлических артефактов вы получаете неземное эхо. Это требует множества преобразований Фурье, и оригинальное приложение использует для этого библиотеку Kiss FFT. Я не хотел зависеть от внешней библиотеки, так что в итоге реализовал простое дискретное преобразование Фурье на GPU. Потребовалось много времени, чтобы правильно это реализовать, но в конце концов оно стоило того. Реализация шейдера GLSL очень компактная и работает довольно быстро, несмотря на свою брутфорсовую природу.
Теперь стало возможным наматывать витки эмбиентного гудения, если в качестве исходных данных есть какой-то осмысленный звук. Так что я решил использовать проверенную и протестированную технологию: трекерную музыку. Оно во многом похожа на MIDI2 [70]kasparov [71] от elitegroup (YouTube [72]) используется модуль с дополнительной реверберацией. Если это работало 17 лет назад, то почему не будет сейчас?
Я использовал gm.dls
— встроенный в Windows звуковой банк MIDI (опять старый трюк) и сделал песню с помощью MilkyTracker в формате модуля XM. Этот формат использовался ещё для многих демок под MS-DOS в 90-е годы.
Я использовал MilkyTracker для сочинения оригинальной песни. Окончательный файл модуля очищен от сэмплов инструментов, а вместо них поставлены параметры смещения и длин из gm.dls
Подвох с gm.dls
в том, что инструменты Roland от 1996 года звучат очень архаично и некачественно. Но оказалось, что в этом нет никакой проблемы, если погрузить их в тонну ревербераций! Вот пример, в котором сначала играет короткая тестовая песня, а затем растянутая версия:
На удивление атмоферно, согласитесь? Так что да, я сделал песню, которая имитирует голливудскую музыку, и она классно получилась. Это в целом всё, что касается музыкальной стороны.
Спасибо varko за помощь в некоторых технических деталях этой статьи.
↑ [79]
Автор: m1rko
Источник [80]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/rabota-s-video/256953
Ссылки в тексте:
[1] guberniya_final.zip (61.8 kB): https://www.pvsm.ruftp://untergrund.net/users/peisik/guberniya_final.zip
[2] демопати Revision 2017: https://2017.revision-party.net/
[3] dear imgui: https://github.com/ocornut/imgui
[4] kkrunchy: http://www.farbrausch.de/~fg/kkrunchy/
[5] несколько фотографий: http://tf.weimarnetz.de/revision2017/
[6] запись всего соревнования: https://www.youtube.com/watch?v=1jv0woZONvc
[7] varko: https://twitter.com/martin_b_radev
[8] noby: https://twitter.com/nnnnoby
[9] branch: https://twitter.com/nicebranch
[10] Полный размер: http://www.lofibucket.com/articles/img/64k/sketch2.jpg
[11] Eldion Passageway: http://anthonyscime.deviantart.com/art/Eldion-Passageway-304528786
[12] этого славного видео об Исландии: https://vimeo.com/189904045
[13] Полная раскадровка: http://www.lofibucket.com/articles/img/64k/story12.jpg
[14] Полный размер: http://www.lofibucket.com/articles/img/64k/starship.jpg
[15] Pheromone: http://www.pouet.net/prod.php?which=67435
[16] YouTube: https://www.youtube.com/watch?v=BTZs8ppUtSQ
[17] Полный размер: http://www.lofibucket.com/articles/img/64k/vs.png
[18] Ground Control: https://github.com/edoreshef/ground-control
[19] GNU Rocket: https://github.com/rocket/rocket
[20] досадные ограничения: https://github.com/rocket/rocket/issues/63
[21] некоторых: http://peisik.untergrund.net/engines/
[22] Tiny C Runtime Library: https://www.codeproject.com/Articles/15156/Tiny-C-Runtime-Library
[23] Питера Шоффхаузера: http://www.musicdsp.org/showone.php?id=246
[24] benshoof.org: http://www.benshoof.org/blog/minicrt/
[25] ntdll.dll из Wine: https://github.com/wine-mirror/wine/blob/77887b474e60d21157cc1c59784b2b4c6c42dedf/dlls/ntdll/misc.c#L218
[26] Пример создания окна WinAPI: https://gist.github.com/seece/1f67da14d69b9c8a75a7e6839abf8e72
[27] Пример инициализации OpenGL: https://gist.github.com/seece/9f5f3069130c4fe642f4fd5e7375816a
[28] glext.h: https://www.khronos.org/registry/OpenGL/api/GL/glext.h
[29] wglext.h: https://www.khronos.org/registry/OpenGL/api/GL/wglext.h
[30] Whole Program Optimization: https://msdn.microsoft.com/en-us/library/0zza0de8.aspx
[31] проблемы с memcpy: http://stackoverflow.com/a/2945619
[32] hg_sdf: http://mercury.sexy/hg_sdf/
[33] Иньиго Куилез: http://iquilezles.org/www/
[34] ShaderToy: https://www.shadertoy.com/
[35] вот большой pdf с описанием: http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf
[36] Полный размер: http://www.lofibucket.com/articles/img/64k/constant_shadows.jpg
[37] каскадными теневыми картами: https://msdn.microsoft.com/en-us/library/windows/desktop/ee416307(v=vs.85).aspx
[38] численным шумом: http://www.iquilezles.org/www/articles/morenoise/morenoise.htm
[39] 1: #1
[40] старую статью об этой технике: http://iquilezles.org/www/articles/terrainmarching/terrainmarching.htm
[41] классной сценой тропического леса на ShaderToy: https://www.shadertoy.com/view/4ttSWf
[42] экспоненциально распределённый шум: http://jcgt.org/published/0004/02/01/
[43] Полный размер: http://www.lofibucket.com/articles/img/64k/terrain_green.jpg
[44] небольшой хак с тенями: http://www.iquilezles.org/www/articles/rmshadows/rmshadows.htm
[45] довольно неплохо в действии: http://www.lofibucket.com/articles/img/64k/shadow.gif
[46] хитрости рейкастинга: http://erleuchtet.org/~cupe/permanent/enhanced_sphere_tracing.pdf
[47] Mercury: http://mercury.sexy/
[48] behind elevated: http://www.iquilezles.org/www/material/function2009/function2009.pdf
[49] Фан Хо: http://www.fanhophotography.com/hong-kong-yesterday.html
[50] Полный размер: http://www.lofibucket.com/articles/img/64k/alley1.jpg
[51] Полный размер: http://www.lofibucket.com/articles/img/64k/alley2.jpg
[52] Полный размер: http://www.lofibucket.com/articles/img/64k/alley3.jpg
[53] Полный размер: http://www.lofibucket.com/articles/img/64k/alley4.jpg
[54] Полный размер: http://www.lofibucket.com/articles/img/64k/alley5.jpg
[55] Полная версия: http://www.lofibucket.com/articles/img/64k/bomber_far.png
[56] bomber_sdf.glsl: https://gist.github.com/seece/dcc4e1a6a68f0a911ad05e3be755588b
[57] Полный размер: http://www.lofibucket.com/articles/img/64k/bomber.png
[58] спасибо, mudlord: https://github.com/dolphin-emu/dolphin/blob/master/Data/Sys/Shaders/FXAA.glsl
[59] описанной Джоном Чэпмэном: http://john-chapman-graphics.blogspot.fi/2013/02/pseudo-lens-flare.html
[60] Полный размер: http://www.lofibucket.com/articles/img/64k/bigdof.jpg
[61] технике DICE: https://www.slideshare.net/DICEStudio/five-rendering-ideas-from-battlefield-3-need-for-speed-the-run
[62] Полный размер: http://www.lofibucket.com/articles/img/64k/wires.jpg
[63] вихревого шума: http://prideout.net/blog/?p=63
[64] VST-плагина: https://en.wikipedia.org/wiki/Virtual_Studio_Technology
[65] V2 Synthesizer: http://www.pouet.net/prod.php?which=15073
[66] element/gesture 61%: https://www.youtube.com/watch?v=Sr5Jh5hqfAA
[67] paulstretched: http://hypermammut.sourceforge.net/paulstretch/
[68] что он может сделать из звука приветствия Windows 98: https://www.youtube.com/watch?v=Fai5s3Zn7b4
[69] в этом интервью с автором: http://www.microscopics.co.uk/blog/2010/paulstretch-an-interview-with-paul-nasca/
[70] 2: #2
[71] kasparov: http://www.pouet.net/prod.php?which=374
[72] YouTube: https://www.youtube.com/watch?v=svkjjNt7J5Q
[73] Феррис из группы Logicoma показывает свой набор инструментов для создания демок 64k: https://www.youtube.com/watch?v=woqksTHNbvk
[74] Engage: https://www.youtube.com/watch?v=GjuridCR2Fo
[75] Исходники некоторых демок Ctrl-Alt-Test: https://github.com/laurentlb/Ctrl-Alt-Test/tree/master/
[76] H-Immersion: https://www.youtube.com/watch?v=HpAMtE4i8zg
[77] https://mobile.twitter.com/iquilezles/status/863692824100782080: https://mobile.twitter.com/iquilezles/status/863692824100782080
[78] ↑: #1_1
[79] ↑: #2_2
[80] Источник: https://habrahabr.ru/post/330090/
Нажмите здесь для печати.