
3.3. Високорівнева мова шейдерів
XNA підтримує програмування шейдерів з використанням високорівневої мови шейдерів (High Level Shading Language, HLSL). У HLSL є невеликий набір функцій, що включає математичні операції, доступ до текстур і керування потоком виконання. Підтримувані HLSL типи даних схожі на типи, які використовуються в мові C, за винятком векторів, матриць та об'єктів вибірки.
Типи даних. HLSL підтримує багато різних типів даних, включаючи скаляри, вектори, матриці та об'єкти вибірки. В таблиці 3.1 показані представлені в мові скалярні типи даних. Для всіх представлених у мові скалярних типів даних можна створювати вектори і матриці, такі як float2, float4, bool3x3, double2x2 і т.д.
Таблиця 3.1
Скалярні типи даних
Тип |
Значення |
bool |
true або false |
int |
32-розрядне ціле із знаком |
half |
16-розрядне з плаваючою крапкою |
float |
32-розрядне з плаваючою крапкою |
double |
64-розрядне з плаваючою крапкою |
Продовження
таблиці 3.1
Іншим представленим в HLSL типом даних є тип Sampler, який використовується для того, щоб зчитувати (вибирати) дані з текстур. Є декілька різних типів об'єктів вибірки, таких як Sampler, Sampler1D, Sampler2D та Sampler3D, що використовуються для вибірки з одновимірних, двовимірних та тривимірних текстур. Об'єкт вибірки має кілька пов'язаних з ним станів, що задають текстуру, з якої виробляється вибірка, застосовуваний тип фільтрації та режим адресації (обгортання) текстури.
У HLSL є два різновиди вхідних типів даних: постійні й змінні. Постійними вхідними даним є такі дані, що залишаються в шейдерах постійними в ході обробки всіх вхідних даних. Наприклад, під час візуалізації машини текстура і світова матриця постійні.
У шейдерах постійні вхідні дані, зазвичай, оголошуються як глобальні змінні, на початку шейдера поза області видимості функцій. Постійні змінні використовуються та встановлюються додатком з використанням їхніх імен.
Змінні вхідні дані – це такі дані, які змінюються при кожному виконанні шейдера. Наприклад, під час візуалізації машини всі вершини моделі машини передаються етапу обробки вершин. Таким чином, кожен раз при виконанні, вершинний шейдер отримує в якості вхідних даних вершину з відмінними атрибутами (місцем розташування, кольором, нормаллю і т.д.). Тому, атрибути вершин не постійні в процесі візуалізації всієї машини. На відміну від постійних вхідних даних, змінні вхідні дані оголошуються в додатку, використовуючи семантику.
HLSL використовує семантику для відображення вхідних та вихідних даних на змінні. Наприклад, можна використовувати семантику POSITION0 на етапі обробки вершин, щоб відобразити атрибути місця розташування кожної вершини на не постійну змінну наступним чином:
float4 vertexPosition : POSITION0.
Семантика потрібна для всіх змінних вхідних даних, які отримуються з програми або передаються між етапами візуалізації. Наприклад, всім вихідним даним вершинного шейдера, які будуть використовуватися в піксельному шейдері, повинна бути призначена семантика. Семантика нечутлива до регістру символів і задається після імені змінної через двокрапку (:). В таблиці 3.2 показані деякі семантики вершинних шейдерів. В таблиці 3.3 показана вихідна семантика вершинних шейдерів.
Таблиця 3.2
Семантики вершинних шейдерів
Вхідна семантика |
Опис |
Тип |
POSITION[n] |
Місце розташування вершини в просторі об’єкту |
float4 |
COLOR[n] |
Розсіюваний та відбиваємий колір |
float4 |
NORMAL[n] |
Вектор нормалі |
float4 |
TEXCOORD[n] |
Координати текстури |
float4 |
TANGENT[n] |
Вектор дотичної |
float4 |
BINORMAL[n] |
Вектор бінормалі |
float4 |
BLENDINDICES[n] |
Індекси змішування |
int4 |
Таблиця 3.3
Вихідна семантика
Вихідна семантика |
Опис |
Тип |
POSITION[n] |
Місце розташування вершини в однорідному просторі (X, Y, Z, W) |
float4 |
COLOR[n] |
Розсіюваний та відбиваємий колір |
float4 |
TEXCOORD[n] |
Координати текстури |
float4 |
FOG[n] |
Туман вершини |
float |
Найбільш часто використовуються семантики POSITION, COLOR, NORMAL і TEXCOORD. Семантики TANGENT і BINORMAL застосовуються, якщо у вершини є вектор дотичної (tangent) або вектор бінормалі (binormal), які перпендикулярні вектору нормалі вершини. Ці три вектори використовуються для створення системи координат, яка буде паралельна поверхні об'єкта в заданій точці, яка називається дотичним простором. Семантики BLENDINDICES і BLENDWEIGHT використовуються тоді, коли вершини пов'язані з кістками (bone). Кістки використовуються для деформування вершин сітки.
Звернемо увагу, що [n] – це необов'язкове ціле число, що визначає кількість використовуваних ресурсів. Наприклад, якщо у моделі три текстури, [n] в семантиці TEXCOORD може варіюватися від 0 до 2. Таким чином, допустимими вхідними семантиками для вершинного шейдера будуть TEXCOORD0, TEXCOORD1 і TEXCOORD2. У таблиці 3.4 показано деякі семантики піксельних шейдерів та у таблиці 3.5 показано вихідні семантики.
Таблиця 3.4
Семантики піксельних шейдерів
Вхідна семантика |
Опис |
Тип |
COLOR[n] |
Розсіюваний та відбиваємий колір |
float4 |
TEXCOORD[n] |
Координати текстури |
float4 |
Таблиця 3.5
Вихідна семантика
Вихідна семантика |
Опис |
Тип |
COLOR[n] |
Підсумковий колір |
float4 |
DEPTH[n] |
Підсумкова глибина |
float |
Оскільки піксельний шейдер виконується після етапу растеризації, доступними вхідними семантиками є колір пікселя та деякі координати текстури. Координати текстури дозволяють адресуватися до місця розташування в текстурі, відображеному на поточному пікселі. Звернемо увагу, що використовуючи координати текстури існує можливість виводити з вершинного шейдера свої власні довільні дані.
Підсумковими вихідними даними піксельного шейдеру є колір пікселя і його глибина, причому відображення кольору пікселя обов'язкове, а глибину пікселя можна не відображати.
Функції. HLSL дозволяє створювати функції, використовуючи синтаксис, подібний до мови C, де у кожної функції є оголошення та тіло. Оголошення функції містить ім'я функції та тип значення, а також може мати список параметрів. Крім того, в типі, що повертається функцією, може бути пов'язана з ним семантика.
Вбудовані функції. У HLSL є невеликий набір функцій, що включає математичні операції, доступ до текстур і керування потоком виконання. Ці функції називаються вбудованими, оскільки вони реалізовані в HLSL і не завжди безпосередньо відображаються на інструкції асемблера GPU. Фактично, багатьом з цих інструкцій відповідає кілька команд асемблера GPU, і вони, ймовірно, забезпечать краще виконання поставленого завдання. У таблиці 3.6 показані деякі з наявних у HLSL функцій.
Таблиця 3.6
Вбудовані функції HLSL
Функція |
Опис |
dot |
Вертає скалярний добуток двох векторів |
cross |
Вертає векторний добуток двох тривимірних векторів з плаваючою крапкою |
lerp |
Виконує лінійну інтерполяцію між двома значеннями |
mul |
Виконує матричне множення X та Y |
normalize |
Нормалізує заданий вектор з плаваючою крапкою |
pow |
Вертає X в степені Y |
reflect |
Вертає вектор відображення, отримуючи направлення вхідного променя та нормаль поверхні |
refract |
Вертає вектор переломлення, використовуючи направлення вхідного променя, нормаль поверхні та коефіцієнт переломлення |
saturate |
Обмежує задане значення діапазоном від 0 до 1 |
tex2d |
Виконує перегляд двомірної текстури |
Продовження
таблиці 3.6
Ефекти. Ефекти – це сутності, які можуть зберігати різні шейдери, техніки та конфігурації для фіксованих етапів конвеєра візуалізації. Окрім шейдерів, в ефекті повинна бути одна або декілька технік. Техніка використовується для того, щоб визначити, як шейдери, що знаходяться всередині ефекту, повинні бути скомпільовані та скомпоновані для візуалізації. Наприклад, оскільки в ефекті може бути багато вершинних і піксельних шейдерів, кожна техніка повинна визначити свою комбінацію (компоновку) вершинних та піксельних шейдерів. У техніках також може бути більше одного проходу, і весь процес візуалізації повторюється для кожного проходу. Більше того, всередині техніки можна конфігурувати деякі параметри етапів растеризації та об'єднання виводу.
Використання ефектів полегшує програмування шейдерів, дозволяючи повторно використовувати код шейдера в різних техніках, а також створювати різні техніки, націлені на слабкі та потужні графічні процесори.