Что такое шейдеры? Просто о сложном для начинающих

Что такое шейдеры? Просто о сложном для начинающих

«Что такое шейдеры?» – очень частый вопрос любопытных игроков и начинающих игровых разработчиков. В этой статье доходчиво и понятно об этих страшных шейдерах расскажу.

Двигателем прогресса в сторону фотореалистичности картинки в компьютерной графике я считаю именно компьютерные игры, поэтому давайте именно в разрезе видео-игр и поговорим о том, что такое “шейдеры”.

До того, как появились первые графические ускорители, всю работу по отрисовке кадров видеоигры выполнял бедняга центральный процессор.

Отрисовка кадра, довольно рутинная работа на самом деле: нужно взять “геометрию” – полигональные модели (мир, персонаж, оружие и т.д.) и растеризовать. Что такое растеризовать? Вся 3d модель состоит из мельчайших треугольников, которые растеризатор превращает в пиксели (то есть “растеризовать” значит превратить в пиксели). После растеризации взять текстурные данные, параметры освещенности, тумана и тп и рассчитать каждый результирующий пиксель игрового кадра, который будет выведен на экран игроку.

Так вот, центральный процессор (CPU – Central Processing Unit) слишком умный парень, чтобы заставлять его заниматься такой рутиной. Вместо этого логично выделить какой-то аппаратный модуль, который разгрузит CPU, чтобы тот смог заниматься более важным интеллектуальным трудом.

Таким аппаратным модулем стал – графический ускоритель или видеокарта (GPU – Graphics Processing Unit). Теперь CPU подготавливает данные и загружает рутинной работой коллегу. Учитывая, что GPU сейчас это не просто один коллега, это толпа миньонов-ядер, то он с такой работой справляется на раз.

Но мы пока не получили ответа на главный вопрос: Что такое шейдеры? Подождите, я подвожу к этому.

Хорошая, интересная и близкая к фото-реализму графика, требовала от разработчиков видеокарт реализовывать многие алгоритмы на аппаратном уровне. Тени, свет, блики и так далее. Такой подход – с реализацией алгоритмов аппаратно называется “Фиксированный пайплайн или конвейер” и там где требуется качественная графика он теперь не встречается. Его место занял “Программируемый пайплайн”.

Запросы игроков “давайте, завозите хороший графоний! удивляйте!”, толкали разработчиков игр (и производителей видеокарт соответственно) все к более и более сложным алгоритмам. Пока в какой-то момент зашитых аппаратных алгоритмов им стало слишком мало.

Наступило время видеокартам стать более интеллектуальными. Было принято решение позволить разработчикам программировать блоки графического процессора в произвольные конвейеры, реализующие разные алгоритмы. То есть разработчики игр, графические программисты отныне смогли писать программы для видеокарточек.

И вот, наконец, мы дошли до ответа на наш главный вопрос.

“Что такое шейдеры?”

Ше́йдер (англ. shader — затеняющая программа) — это программа для видеокарточки, которая используется в трёхмерной графике для определения окончательных параметров объекта или изображения, может включать в себя описание поглощения и рассеяния света, наложения текстуры, отражения и преломление, затенение, смещение поверхности и множество других параметров.

Что такое шейдеры? Картинка с демонстрацией, того какие эффекты можно получить с помощью шейдеров.
Что такое шейдеры? Например, вот такой эффект можно получить, это шейдер воды примененный к сфере.

Графический пайплайн

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

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

Помимо графических задач с такими интеллектуальными видеокартами появилась возможность выполнения на GPU вычислений общего назначения (не связанных с компьютерной графикой).

Впервые полноценная поддержка шейдеров появилась в видеокартах серии GeForce 3, но зачатки были реализованы ещё в GeForce256 (в виде Register Combiners).

Виды шейдеров

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

Вершинный шейдер (Vertex Shader)

Вершинными шейдерами делают анимации персонажей, травы, деревьев, создают волны на воде и многие другие штуки. В вершинном шейдере программисту доступны данные, связанные с вершинами например: координаты вершины в пространстве, её текстурные координатами, её цвет и вектор нормали.

Геометрический шейдер (Geometry Shader)

Геометрические шейдеры способны создавать новую геометрию, и могут использоваться для создания частиц, изменения детализации модели «на лету», создание силуэтов и т.п. В отличие от предыдущего вершинного, способны обработать не только одну вершину, но и целый примитив. Примитивом может быть отрезок (две вершины) и треугольник (три вершины), а при наличии информации о смежных вершинах (англ. adjacency) для треугольного примитива может быть обработано до шести вершин.

Пиксельный шейдер (Pixel/Fragment Shader)

Пиксельными шейдерами выполняют наложение текстур, освещение, и разные текстурные эффекты, такие как отражение, преломление, туман, Bump Mapping и пр. Пиксельные шейдеры также используются для пост-эффектов.

Пиксельный шейдер работает с фрагментами растрового изображения и с текстурами — обрабатывает данные, связанные с пикселями (например, цвет, глубина, текстурные координаты). Пиксельный шейдер используется на последней стадии графического конвейера для формирования фрагмента изображения.

Вычислительный шейдер (Compute Shader)

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

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

Вычислительные шейдеры доступны и для разработчиков игр, так как современные графические API предоставляют возможность разработчикам игр использовать их для различных задач (среди которых например: GPU-частицы, skinning и т.д.)

На чем пишут шейдеры?

Изначально шейдеры можно было писать на assembler-like языке, но позже появились шейдерные языки высокого уровня, похожие на язык С, такие как: Cg, GLSL и HLSL.

Такие языки намного проще чем C, ведь задачи решаемые с их помощью, гораздо проще. Система типов в таких языках отражает нужды программистов графики. Поэтому они предоставляют программисту специальные типы данных: матрицы, семплеры, векторы и тп.

RenderMan

Все что мы обсудили выше относится к realtime графике. Но существуют non-realtime графика. В чем разница – realtime – реальное время, тоесть здесь и сейчас – давать 60 кадров в секунду в игре, это процесс реального времени. А вот рендерить комплексный кадр для ультрасовременной анимации по несколько минут это non-realtime. Суть во времени.

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

Супер-реалистичная графика в Sand piper

Например, посмотрите, на вот этот милый мультфильм, песчинки, перышки птички, волны, все выглядит невероятно реальным.

*Видео могут забанить на Youtube, если оно не открывается, погуглите pixar sandpiper – короткометражный мультфильм про храброго песочника очень милый и пушистый. Умилит и продемонстрирует насколько крутой может быть компьютерная графика.

Так вот это RenderMan от фирмы Pixar. Он стал первым языком программирования шейдеров. API RenderMan является фактическим стандартом для профессионального рендеринга, используется во всех работах студии Pixar и не только их.

Полезная информация

Теперь Вы знаете что такое шейдеры, но помимо шейдеров, есть другие очень интересные темы в разработке игр и компьютерной графике, которые наверняка Вас заинтересуют:

  • Партиклы (системы частиц),- техника создания потрясающих эффектов в современных видео-играх. Обзорная статья и видео с уроками создания эффектов в Unity3d
  • Для начинающего Unity3d программиста,- если Вы задумываетесь о разработке видеоигр, в качестве профессиональной карьеры или хобби, эта статья содержит отличный набор рекомендаций “с чего начать”, “какие книги читать” и т.д.

Если остались вопросы

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

Понравилась статья? Поделиться с друзьями:
Автор snezhok_13
Время от времени пишет статьи о разработке игр и проводит интервью с разработчиками. Сейчас работает engine-progremmer'ом в Larian Studios. Большой поклонник игр Naughty Dog.
  1. Жду статью про графический конвейер )

  2. Андрей Мартьянов :

    Хорошо пишешь, гоу статью про конвеер!

  3. Иван Иванов :

    Спасибо за статью Сергей! Очень интересно. Жду про конвеер.

    • Привет, статья будет в течение нескольких недель, я думаю. Как бы это все разобрать не скатываясь в уроки по программированию шейдеров :) Ещё думаю будет здорово рассмотреть в общем “что такое рендеринг”, может даже до конвейера…

      • Влад Тычинский :

        Так, надо было срзу про рендеринг писать! В потом уже детализировать: как ренерятся партиклы, как разные движки делят информацию о кадре на вызовы отрисовки, что такое шейдер и т. д.. А потом детализировать детали: тот же конвеер (кстати, жду, пока ты про него напишешь).

        • Да) это было бы вернее, если бы я заранее знал, что эти статьи кому-то понадобятся :) Я ведь просто решил скомпилировать простое объяснение для интересующихся) Значит начну с рендеринга. Пусть следующая статья будет про рендеринг. Так сказать “приквел” :)

          Про то как разные движки делят информацию о вызовах это очень интересно, именно архитектура многопоточного рендерера… Я про такое сам с удовольствием почитаю!

  4. Фёдор Ворошилов :

    Жду статью про графический конвейер

  5. Pavel Zabelin :

    Спасибо, хорошее введение в тему. Детальное продолжение будет?

  6. bkostya :

    Здравствуй Сергей. Я, новичок. Решил познакомиться с работой на СИ. Начал с простого – примитивы. Вроде понравилось, только скучно и захотелось заставить их двигаться. Роясь в сети наткнулся на слово шейдер и, соответственно, на твою статью. Я мысленно представил пропасть между примитивом и шейдером. Понимаю, тебе может быть не интересно возиться с азами, но может ты поможешь мне преодолеть эту пропасть. Обозначь ступени, ступая по которым, любой начинающий смог бы достичь мастерства шейдерного программирования.

  7. bkostya :

    Здравствуй Сергей. По твоему совету начал читать The Book of Shaders, онлайн. И, ожидаемо, споткнулся на первом же уроке – Hello world! Не смог выполнить задание с процедурой.
    /* Объявите отдельную функцию, которая возвращает заданный цвет, и используйте её внутри main(). Например вот это код функции, которая возвращает красный:
    vec4 red(){
    return vec4(1.0,0.0,0.0,1.0);*/
    Как пользоваться процедурами на СИ я знаю, но здесь что-то не работает? Подскажи, каких знаний мне не хватает для данного задания.
    ЗЫ. на сайте не нашел обратной связи, не знаю к кому там можно обратиться.

  8. bkostya :

    thebookofshaders.com это сайт,которым я пользуюсь.

  9. bkostya :

    Конкретный вопрос актуален, а так, я уже понял каких знаний не хватает. Читаю красную книгу.

    • Так, и что не получается? Код функции у тебя есть:
      vec4 red()
      {
      return vec4(1.0,0.0,0.0,1.0);
      }

      как пользоваться функциями на С вы знаете:

      void main() {
      gl_FragColor = red();
      }

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

  10. 99174 :

    теперь понятно почему моды на сталкер всё время вылетают. вот он – юный програмист!гат-оф-тесь.

  11. LancerEVO9 :

    в предложении “Учитывая, что GPU сейчас это не просто один коллега, это толпа миньонов-ядер, то он с такой работой справляется на раз.” написано “миньонов”, а по идее должно быть миллионов. Видимо кто-то слишком доверяет рамочным программам которые толкают человечество в пропасть ограниченной функциональности в угоду коллективной шейдерности и служения общему благу, более выстраданной картинке для последующих уровней. Вопрос в том кто собирает сливки? Или же это порождает бесконечные вселенные ?
    Кто знает – ответьте, ибо я схожу с ума, где такое применять на практике?)

    • Добрый день, там именно “миньоны” – метафора о том, что это огромное количество “подчинённых”, которые выполняют большое количество задач.
      Последующие вопросы я не понял, переформулируйте, пожалуйста.

  12. Светлана :

    Спасибо за статью. Очень познавательно

  13. Олег Игоревич :

    Спасибо за статью! Интересно и полезно, к тому же, художественно.

    “получить в реальном времени мы сейчас получить” – два раза “получить”

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *