• Рисуем мультяшный взрыв за 180 строчек голого C++

    • Tutorial
    Неделю назад я опубликовал очередную главу из моего курса лекций по компьютерной графике; сегодня опять возвращаемся к трассировке лучей, но на сей раз пойдём самую чуточку дальше отрисовки тривиальных сфер. Фотореалистичность мне не нужна, для мультяшных целей подобный взрыв, как мне кажется, сойдёт.

    Как всегда, в нашем распоряжении только голый компилятор, никаких сторонних библитек использовать нельзя. Я не хочу заморачиваться с оконными менеджерами, обработкой мыши/клавиатуры и тому подобным. Результатом работы нашей программы будет простая картинка, сохранённая на диск. Я совершенно не гонюсь за скоростью/оптимизацией, моя цель — показать основные принципы.

    Итого, как в таких условиях нарисовать вот такую картинку за 180 строчек кода?


    Читать дальше →
  • Корпоративное интервью

      — Сергей! Сергей!

      Сергей встрепенулся, оторвался от компьютера и снял наушники. Сбоку стояла Лена, менеджер по снабжению, с какими-то бумагами в руках и вопросительно на него смотрела.

      — Чего? – спросил Сергей.

      — Интервью.

      — Чего?

      — Мы с вами договаривались об интервью для корпоративного журнала.

      — Блин, точно… Прямо сейчас? Я тут поработать хотел, специально вышел в каникулы…

      — Прямо сейчас. – твердо сказала Лена. – Я, как вы заметили, тоже специально вышла в каникулы, и только ради интервью.

      — А, да, точно… — Сергей начал волноваться. – Ладно, давайте. Надолго это?

      — Не знаю. – пожала плечами Лена. – Вопросов много, быстрее начнем – быстрее закончим.
      Читать дальше →
    • Пишем свой язык программирования, часть 2: промежуточное представление программ

      • Tutorial
      image

      Введение


      Приветствую всех, кто заглянул почитать мою очередную статью.

      Повторюсь, я описываю создание языка языка программирования, на основе проведенной ранее работы, результаты которой описал в этом посте.

      В первой части (линк: habr.com/post/435202) я описал этапы проектирования и написания языковой ВМ, которая будет выполнять наши будущие приложения на нашем будущем языке.
      В этой статье я планирую описать основные этапы создания промежуточного языка программирования, который будет собираться в абстрактный байткод для уже непосредственного выполнения на нашей ВМ.

      Думаю, что не помешает сразу привести ссылки на сайт проекта и его репозиторий.

      Сайт
      Репозиторий
      Читать дальше →
      • +14
      • 11,1k
      • 1
    • Рендеринг шрифтов с помощью масок покрытия, часть 1

      • Перевод
      image

      Когда мы приступали к разработке нашего профилировщика производительности, то знали, что будем выполнять почти весь рендеринг UI самостоятельно. Вскоре нам пришлось решать, какой подход выбрать для рендеринга шрифтов. У нас были следующие требования:

      1. Мы должны иметь возможность рендерить любой шрифт любого размера в реальном времени, чтобы адаптироваться к системным шрифтам и их размерам, выбранным пользователями Windows.
      2. Рендеринг шрифтов должен быть очень быстрым, никаких торможений при рендеринге шрифтов не допускается.
      3. В нашем UI куча плавных анимаций, поэтому текст должен иметь возможность плавно перемещаться по экрану.
      4. Он должен быть читаемым при малых размерах шрифтов.

      Не будучи в то время большим специалистом в этом вопросе, я поискал информацию в Интернете и нашёл множество техник, используемых для рендеринга шрифтов. Также я пообщался с техническим директором Guerrilla Games Михилем ван дер Леу. Эта компания экспериментировала со множеством способов рендеринга шрифтов и их движок рендеринга был одним из лучших в мире. Михиль вкратце изложил мне свою идею новой техники рендеринга шрифтов. Хотя нам вполне было бы достаточно уже имевшихся техник, меня эта идея заинтриговала и я приступил к её реализации, не обращая внимания на открывшийся мне чудесный мир рендеринга шрифтов.
      Читать дальше →
    • Пишем собственную виртуальную машину

      • Перевод
      • Tutorial
      В этом руководстве я расскажу, как написать собственную виртуальную машину (VM), способную запускать программы на ассемблере, такие как 2048 (моего друга) или Roguelike (моя). Если вы умеете программировать, но хотите лучше понять, что происходит внутри компьютера и как работают языки программирования, то этот проект для вас. Написание собственной виртуальной машины может показаться немного страшным, но я обещаю, что тема удивительно простая и поучительная.

      Окончательный код составляет около 250 строк на C. Достаточно знать лишь основы C или C++, такие как двоичная арифметика. Для сборки и запуска подходит любая Unix-система (включая macOS). Несколько API Unix используются для настройки ввода и отображения консоли, но они не являются существенными для основного кода. (Реализация поддержки Windows приветствуется).

      Примечание: эта VM — грамотная программа. То есть вы прямо сейчас уже читаете её исходный код! Каждый фрагмент кода будет показан и подробно объяснён, так что можете быть уверены: ничего не упущено. Окончательный код создан сплетением блоков кода. Репозиторий проекта тут.
      Читать дальше →
    • Карты из шестиугольников в Unity: круговорот воды, эрозия, биомы, цилиндрическая карта

      • Перевод
      Части 1-3: сетка, цвета и высоты ячеек

      Части 4-7: неровности, реки и дороги

      Части 8-11: вода, объекты рельефа и крепостные стены

      Части 12-15: сохранение и загрузка, текстуры, расстояния

      Части 16-19: поиск пути, отряды игрока, анимации

      Части 20-23: туман войны, исследование карты, процедурная генерация

      Части 24-27: круговорот воды, эрозия, биомы, цилиндрическая карта

      Часть 24: регионы и эрозия


      • Добавляем границу из воды вокруг карты.
      • Разделяем карту на несколько регионов.
      • Применяем эрозию, чтобы срезать обрывы.
      • Перемещаем сушу, чтобы сгладить рельеф.

      В предыдущей части мы заложили основы процедурной генерации карт. На этот раз мы ограничим места возможного появления суши и воздействуем на неё эрозией.

      Этот туториал создан в Unity 2017.1.0.


      Разделяем и сглаживаем сушу.
      Читать дальше →
    • Написание шейдеров в Unity. GrabPass, PerRendererData

      Привет! Я хотел бы поделиться опытом написания шейдеров в Unity. Начнем с шейдера искажения пространства (Displacement/Refraction) в 2D, рассмотрим функционал, используемый для его написания (GrabPass, PerRendererData), а также уделим внимание проблемам, которые обязательно возникнут.

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


      Читать дальше →
      • +53
      • 13,4k
      • 8
    • Шейдеры растворения и исследования мира

      • Перевод

      Часть 1: шейдер растворения


      Шейдер растворения возвращает красивый эффект, к тому же его легко создать и понять; сегодня мы сделаем его в Unity Shader Graph, а также напишем на HLSL.

      Вот пример того, что мы будем создавать:



      Как это работает


      Чтобы создать шейдер растворения (dissolve shader), нам придётся работать со значением AlphaClipThreshold в шейдере «Shader Graph» или воспользоваться функцией HLSL под названием clip.

      По сути, мы прикажем шейдеру не рендерить пиксель на основании текстуры и переданного значения. Нам нужно знать следующее: белые части растворяются быстрее.
      Читать дальше →
      • +47
      • 10,9k
      • 3
    • Карты из шестиугольников в Unity: вода, объекты рельефа и крепостные стены

      • Перевод
      Части 1-3: сетка, цвета и высоты ячеек

      Части 4-7: неровности, реки и дороги

      Части 8-11: вода, объекты рельефа и крепостные стены

      Части 12-15: сохранение и загрузка, текстуры, расстояния

      Части 16-19: поиск пути, отряды игрока, анимации

      Части 20-23: туман войны, исследование карты, процедурная генерация

      Части 24-27: круговорот воды, эрозия, биомы, цилиндрическая карта

      Часть 8: вода


      • Добавляем в ячейки воду.
      • Триангулируем поверхность воды.
      • Создаём прибой с пеной.
      • Объединяем воду и реки.

      Мы уже добавили поддержку рек, а в этой части полностью погрузим ячейки в воду.


      Вода прибывает.
      Читать дальше →
      • +30
      • 6,2k
      • 2
    • Карты из шестиугольников в Unity: части 1-3

      • Перевод
      image

      От переводчика: эта статья — первая из подробной (27 частей) серии туториалов о создании карт из шестиугольников. Вот, что должно получиться в самом конце туториалов.

      Части 1-3: сетка, цвета и высоты ячеек

      Части 4-7: неровности, реки и дороги

      Части 8-11: вода, объекты рельефа и крепостные стены

      Части 12-15: сохранение и загрузка, текстуры, расстояния

      Части 16-19: поиск пути, отряды игрока, анимации

      Части 20-23: туман войны, исследование карты, процедурная генерация

      Части 24-27: круговорот воды, эрозия, биомы, цилиндрическая карта

      Часть 1: создание сетки из шестиугольников


      Оглавление


      • Преобразуем квадраты в шестиугольники.
      • Триангулируем сетку из шестиугольников.
      • Работаем с кубическими координатами.
      • Взаимодействуем с ячейками сетки.
      • Создаём внутриигровой редактор.

      Этот туториал является началом серии о картах из шестиугольников. Сетки из шестиугольников используются во многих играх, особенно в стратегиях, в том числе в Age of Wonders 3, Civilization 5 и Endless Legend. Мы начнём с основ, будем постепенно добавлять новые возможности и в результате создадим сложный рельеф на основе шестиугольников.
      Читать дальше →
    • Learn OpenGL. Урок 5.9 — Отложенный рендеринг

      • Перевод
      • Tutorial

      В предыдущих статьях мы использовали прямое освещение (forward rendering или forward shading). Это простой подход, при котором мы рисуем объект с учётом всех источников света, потом рисуем следующий объект вместе с всем освещением на нём, и так для каждого объекта. Это достаточно просто понять и реализовать, но вместе с тем получается довольно медленно с точки зрения производительности: для каждого объекта придётся перебрать все источники света. Кроме того, прямое освещение работает неэффективно на сценах с большим количество перекрывающих друг друга объектов, так как большая часть вычислений пиксельного шейдера не пригодится и будет перезаписана значениями для более близких объектов.


      Отложенное освещение или отложенный рендеринг (deferred shading или deferred rendering) обходит эту проблему и кардинально меняет то, как мы рисуем объекты. Это даёт новые возможности значительно оптимизировать сцены с большим количеством источников света, позволяя рисовать сотни и даже тысячи источников света с приемлемой скоростью. Ниже изображена сцена с 1847 точечными источниками света, нарисовання с помощью отложенного освещения (изображение предоставил Hannes Nevalainen). Что-то подобное было бы невозможно при прямом расчёте освещения:


      img1

      Читать дальше →
    • Трассировка пути на GPU в Unity — часть 2

      • Перевод
      image

      «Нет ничего хуже чёткого образа размытой концепции». – фотограф Энсел Адамс

      В первой части статьи мы создали трассировщик лучей Уиттеда, способный трассировать идеальные отражения и резкие тени. Но нам не хватает эффектов нечёткости: рассеянного взаимоотражения, глянцевых отражений и мягких теней.

      Основываясь на уже имеющемся у нас коде, мы итеративно решим уравнение рендеринга, сформулированное Джеймсом Каджия в 1986 году и преобразуем наш рендерер в трассировщик пути, способный передавать вышеупомянутые эффекты. Мы снова будем использовать C# для скриптов и HLSL для шейдеров. Код выложен на Bitbucket.
      Читать дальше →
    • Имитация естественного движения: Steering Behaviors — 2

      • Перевод
      Первая часть статьи здесь.


      Часть 6. Избегание коллизий


      Для правильной навигации NPC часто требуется способность избегать препятствий. В этой части мы рассмотрим steering behavior collision avoidance (избегание коллизий), позволяющее персонажам благополучно уворачиваться от препятствий в окружении.



      Введение


      Основная идея избегания коллизий заключается в генерировании управляющей силы для уклонения от препятствий каждый раз, когда они достаточно близки, чтобы препятствовать движению. Даже если в окружении есть несколько препятствий, это поведение будет одновременно использовать одно из них для вычисления силы избегания.

      Анализируются только препятствия перед персонажем; для оценки выбирается ближайшее, как представляющее наибольшую угрозу. В результате у персонажа появляется способность уклоняться от всех препятствий в области, благополучно и без запинок переходя от одного к другому.


      Анализируются препятствия перед персонажем и выбирается ближайшее (наиболее угрожающее).

      Поведение избежания коллизий — это не алгоритм поиска путей. Оно заставляет персонажей двигаться по окружению, избегая препятствий, постепенно находя путь сквозь блоки — но в случаях с препятствиями в виде L или T, например, оно действует не очень хорошо.
      Читать дальше →
      • +23
      • 7,3k
      • 2
    • Learn OpenGL. Урок 5.3 — Карты теней

      • Перевод
      • Tutorial

      Тень — это отсутствие света. Если лучи от источника света не попадают на объект, так как поглощаются другим объектом, то первый объект находится в тени. Тени добавляют реализма к изображению и дают увидеть взаимное расположение объектов. Благодаря ним сцена приобретает "глубину". Сравните следующие изображения сцены с тенями и без:


      with_shadows_and_without


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


      Тени сложновато реализовать, особенно потому что реалтайм алгоритм для идеальных теней ещё не придуман. Существуют несколько хороших способов для приблизительного рассчёта теней, но они все имеют свои особенности, которые надо принимать во внимание.


      Один из методов — карты теней (shadow maps) — относительно простой в реализации, используется в большинстве видеоигр и даёт достойные результаты. Карты теней не так уж и трудно понять, они довольно дёшевы с точки зрения производительности и их легко улучшить до более продвинутых алгоритмов (типа теней от точечного источника света или каскадных карт теней)

      Читать дальше →
    • Глобальное освещение с использованием трассировки вокселей конусами

        В этой статье я расскажу о реализации одного из алгоритмов расчёта глобального (переотражённого / ambient) освещения, применяемого в некоторых играх и других продуктах, — Voxel Cone Tracing (VCT). Возможно, кто-то читал старенькую статью ([VCT]) 2011 года или смотрел видео. Но статья не даёт исчерпывающих ответов на вопросы, как реализовать тот или иной этап алгоритма.


        Рендер сцены без глобального освещения, и с использованием VCT:
        Читать дальше →
        • +39
        • 8,2k
        • 7
      • Оптимизация кода: память

          Большинство программистов представляют вычислительную систему как процессор, который выполняет инструкции, и память, которая хранит инструкции и данные для процессора. В этой простой модели память представляется линейным массивом байтов и процессор может обратиться к любому месту в памяти за константное время. Хотя это эффективная модель для большинства ситуаций, она не отражает того, как в действительности работают современные системы.

          В действительности система памяти образует иерархию устройств хранения с разными ёмкостями, стоимостью и временем доступа. Регистры процессора хранят наиболее часто используемые данные. Маленькие быстрые кэш-памяти, расположенные близко к процессору, служат буферными зонами, которые хранят маленькую часть данных, расположеных в относительно медленной оперативной памяти. Оперативная память служит буфером для медленных локальных дисков. А локальные диски служат буфером для данных с удалённых машин, связанных сетью.

          image

          Иерархия памяти работает, потому что хорошо написанные программы имеют тенденцию обращаться к хранилищу на каком-то конкретном уровне более часто, чем к хранилищу на более низком уровне. Так что хранилище на более низком уровне может быть медленнее, больше и дешевле. В итоге мы получаем большой объём памяти, который имеет стоимость хранилища в самом низу иерархии, но доставляет данные программе со скоростью быстрого хранилища в самом верху иерархии.
          Читать дальше →
        • Профилирование: оптимизация

          • Перевод


          Это вторая статья из серии статей об оптимизации кода. Из первой мы узнали, как находить и анализировать узкие места в коде, снижающие производительность. Мы предположили, что главная проблема в примере — медленное обращение к памяти. В этой статье рассмотрим, как снизить расходы при работе с памятью, а следовательно, и увеличить скорость программы.

          Читать дальше →
          • +32
          • 6,5k
          • 5
        • Физическое моделирование на GPU с использованием compute shader в среде Unity3D

          • Tutorial
          В этом руководстве я расскажу, как использовать compute shader для реализации вычислений на видеокарте — на примере модели волос:
          Читать дальше →
          • +51
          • 20,4k
          • 8
        • Логика камеры в 2D-платформере

          • Перевод
          image


          Правильно настроить поведение камеры в классическом 2D-платформере не так просто, как может казаться.

          Самый простой подход — жёстко привязать камеру к персонажу игрока, чтобы он всегда находился в центре экрана. Это может сойти для прототипов, но такая камера обладает недостатками, которые сильно раздражают игроков.

          Например, если камера сдвигается вверх при каждом прыжке персонажа, то это запросто может вызвать тошноту. Кроме того, при мгновенном разгоне и остановке персонажа камера может резко дёргаться.

          В нашей новой игре Tiny Thor мы экспериментировали с различными вариантами. Я хочу рассказать о том, на каких техниках мы в результате остановились.
          Читать дальше →
        • Трёхмерная графика с нуля. Часть 1: трассировка лучей

          • Перевод
          image


          Эта статья разделена на две основные части, Трассировка лучей и Растеризация, в которых рассматриваются два основных способа получения красивых изображений из данных. В главе Общие концепции представлены некоторые базовые понятия, необходимые для понимания этих двух частей.

          В этой работе мы сосредоточимся не на скорости, а на чётком объяснении концепций. Код примеров написан наиболее понятным образом, который не обязательно является самым эффективным для реализации алгоритмов. Есть множество способов реализации, я выбрал тот, который проще всего понять.

          «Конечным результатом» этой работы будут два завершённых, полностью рабочих рендереров: трассировщик лучей и растеризатор. Хотя в них используются очень отличающиеся подходы, при рендеринге простой сцены они дают схожие результаты:


          Читать дальше →