тяга к революциям TONY (TONY@EYKONTECH.COM) Спецвыпуск: Хакер, номер #064, стр. 064-012-2 поколения процессоров Сравним возможности вершинных и фрагментных процессоров трех поколений. Поскольку первое поколение шейдеров было самым многочисленным (в плане версий), я возьму для сравнения только версию 1.4, остальные практически не отличаются от нее. Для версии шейдеров 2.0 буду рассматривать спецификацию расширенных шейдеров 2.Х. Как видно по сравнительной таблице, с каждым новым поколением возрастает длина шейдеров и количество регистров, что позволяет усложнять и усложнять используемые эффекты. Введение инструкций для управления кодом (циклы, условия) позволяет проверять передаваемые из базового кода, выполняемого обычным CPU, условия и параметры (например позиции источников света). Благодаря этому становится возможным создавать реалистичное попиксельное освещение, зависящее от нескольких различных лампочек, создавать реальные (мягкие) тени, эффекты глубины поверхностей и т.д. вершинный процессор Теперь покопаемся в кишочках каждого процессора, первый в очереди — вершинный. Как видно по диаграмме «Графический конвейер», на его вход попадают вершины треугольников, образующих сцену. Для каждой вершины выполняется вершинный шейдер, заранее загруженный в видеокарту. Посмотри на рисунок «Пример шейдера»: в XML-узле VertexShader содержится код вершинной программы (функция main). Эта программа довольно простая, к каждой вершине она добавляет диффузный цвет и вычисляет значение текстурных координат для специальной текстуры, которые изменяются в зависимости от того, под каким углом мы смотрим на сцену. Однако для того чтобы начать расчет нужных данных, мы должны перевести координаты вершины из базового пространства (единичной системы координат) в мировое пространство — эти вычисления обязательны, если мы хотим, чтобы сцена отображалась на экране с учетом камеры и координат в мировом (сценическом) пространстве. Это преобразование выполняется с помощью строчки: o.pos = mul( i.pos, WorldViewProjection ). Данные о вершине попадают в функцию main() из потока входных данных — это так называемый однородный (uniform) ввод данных, которые попадают в процессор из локальной памяти видеокарты в регистры входных данных (Input registers). Данные, которыми ты влияешь на шейдер из своей управляющей программы, работающей на CPU, попадают в программу через константные регистры (варьируемый вход). Эти данные не могут быть изменены в коде шейдера, поэтому и называются константными. В нашем примере константные данные — различные матрицы (видовая и мировая), а также диффузный цвет вершины. Временные регистры используются для сохранения промежуточных результатов вычислений (в нашем случае — переменные nrm и e2v). Регистр предикатов содержит в себе флаг — некоторое условие, которое может быть задано заранее (извне шейдера) или рассчитано в программе. С помощью этого условия можно повлиять на ход выполнения программы (ветвления). В шейдерах второго поколения (2.0 и 2.Х) возможны ветвления кода, причем в шейдерах версии 2.0 возможны только статические ветвления (циклы и подпрограммы), то есть проверка условий, заданных извне шейдера. В расширенных шейдерах 2.Х возможно и динамическое управление ходом выполнения шейдера. Например, если рассчитанный диффузный цвет вершины красный, то следует делать одно, если красной компоненты не содержится — делать другое. |