Редагуючи будь-яку модель, багато хто в властивостях поверхонь помічав графу shader, в якій вказується щось на зразок models/model або подібні. Як правило, ці шейдери упаковані в shaders.xr і shaders_xrlc.x r, які є своєрідною базою даних шейдерів, зібраних за певними шаблонами.
Але, крім цих баз даних, є ще й скриптові шейдери, які мають пріоритет перед тими шейдерами, що упаковані в *.xr. Це файли, що мають розширення .s і лежать у папках відповідних рендерів. Обчислити правильну назву шейдера в БД та шейдерного скрипта .s можна дуже просто - для прикладу, якщо у нас у БД шейдер знаходиться в model/selflight , то ім'я шейдера має бути model_selflight.s , якщо details/blend, то скрипт шейдера буде відповідно , details_blend.s . Не так уже й складно.
Взагалі база даних з шейдерами була вигадана не тому, що авторам сталкера дуже подобалося плодити екземпляри важкорозпарюваних форматів, а причина більш банальна - щоб збільшити швидкість завантаження гри, заощадивши за рахунок активності жорсткого диска при відкритті файлів скриптових шейдерів у папці відповідного рендера. Плюс до того в цьому випадку зменшується кількість шейдерних файлів, що як мінімум вдвічі зменшує ймовірність помилки – за умови двох рендерів ця економія виходить за рахунок тих шейдерів, які є спільними для обох рендерів. Плюс до того ймовірність помилки ще більше зменшується тим, що бази даних редагуються в СДК, а СДК ці бази даних представляє у вигляді всіляких галочок і полів введення, тому помилка може бути тільки у даних, що вводяться, але не в скриптовому коді шейдерів, який, імовірніше загалом, генерується під час завантаження гри.
Скриптові шейдери використовуються в основному тільки в тих випадках, коли їх код відрізняється для різних рендерів.
З деяких причин я вважаю, що для модобудівників шейдерні скрипти є кращими, ніж поширення своїх шейдерних модів у вигляді модифікованої .xr-БД. Причини в основному дві: По-перше скриптові шейдери надають великі можливості для польоту фантазії, а по-друге поширення шейдерних модів у вигляді скриптових шейдерів все ж таки робить менше ймовірність конфлікту модів, так як різні шейдери будуть у різних файлах, а не всі разом одному хитрому і важкоредагованому, і, що найгірше, - файлі, що важко об'єднується. Тому далі ми розглянемо скриптові шейдери.
Що являють собою шейдерні скрипти? Це звичайні скрипти на lua, які є своєрідною мовою для того, щоб пояснити движку, які завантажувати текстури і які підключати шейдери з наявних .ps і .vs файлів.
- Для тих хто підбадьорився відразу скажу, що незважаючи на те, що шейдерні скрипти написані мовою, яка використовується в ігрових скриптах, це все-таки не одне і те ж. По-перше, шейдерні скрипти виконуються при завантаженні рівня всього один раз (у фазу завантаження "завантаження шейдерів"), тому на малювання в реальному часі впливати нездатні, і крім того, до ігрових скриптів скриптові шейдери доступу не мають.
Ось, наприклад, вміст найпростішого скриптового шейдера:
function normal ( shader, t_base, t_second, t_detail ) shader:begin ( "effects_gradient" , "effects_gradient_p" ) end
Розберемо його по кісточках:
- function normal – оголошення стандартної функції шейдерного скрипту. У деяких шейдерах є ще функції l_spot , l_point , l_special і normal_hq аналогічного змісту, але явно прораховують поведінку цього шейдера в умовах освітлення
- shader - найімовірніше ідентифікатор шейдера у грі, вміст цієї змінної зазвичай є текстовий рядок на кшталт "models_selflight" чи "models/selflight".
- t_base – шлях до текстури, яку слід виводити за допомогою цього шейдера
- t_second , t_detail - шляхи до інших текстур, доки призначення їх невідоме.
- shader:begin( "effects_gradient", "effects_gradient_p") - свята святих шейдера. Якщо точніше – створення об'єкта шейдера як такого.
-
- effects_gradient - ім'я .vs файлу використовуваного в цьому шейдері
- effects_gradient_p - ім'я .ps файлу відповідно.
Після цього рядка можуть бути такі рядки (вони необов'язкові)
- : blend (true, blend.srcalpha, blend.one) - налаштування блендингу для текстур з альфою, наприклад, напівпрозорі текстури без застосування цього рядка будуть виглядати непрозорими чорними в прозорих місцях. Ці методи блендингу відповідають перемикачу в СДК, де варіанти ALPHA-ADD, BLEND, SET і так далі. Приклад вище блендинг відповідає положенню ALPHA-ADD.
-
- true - можливо false - включення обробки текстур, тобто true - обробка включена, false, відповідно, вимкнена.
-
- blend.srcalpha , blend.one - відповідно, методи блендингу, можуть бути:
blend.one blend.zero null
Також ось таблиця, за якою можна вибрати решту параметрів блендингу, вибираючи в таблиці по порядку зліва направо:
src | color | |||
inv | dest | alpha |
тобто:
blend.srccolor blend.invsrccolor blend.destcolor blend.invdestcolor blend.srcalpha blend.invsrcalpha blend.destalpha blend.invdestalpha
- де inv – інверсія, color – колір, alpha – альфа (коефіцієнт прозорості), src – параметр береться до шейдера, dest – параметр береться після шейдера.
- : sorting ( 3, false ) - Порядок відмальовування поверхні по відношенню до самого об'єкта, частиною якого є поверхня.
-
- 3 - цифра порядку відтворення, де 1 - за об'єктом, 2 - на рівні з об'єктом, 3 - спереду об'єкта (ближче до актора). Як правило, при трійці поверхня, що шейдується, буде відмальовуватися поверх всього, в тому числі і зброї.
-
- false - відповідає галочці "srict sorting" у здк. Поки що призначення невідоме.
- : aref (false, 2) - функція перемикає режим тестування пікселів по альфі. Перший аргумент - вкл/выкл, другий аргумент - значення альфи, використовуване порівняно альфи пікселів. Якщо піксель перевірку не пройшов, він не буде малюватись. Як саме відбувається перевірка альфи, поки незрозуміло, функція перевірки встановлюється десь у движку.
- : zb (false, false) - встановлює функцію порівняння пікселів при z-тесті та включає режим запису в z-буфер для текстури. Перший аргумент - функція порівняння (false - D3DCMP_LESSEQUAL - піксель проходить тест тільки якщо його z менше або дорівнює поточному пікселю, true - D3DCMP_ALWAYS - піксель завжди проходить тест). Другий аргумент - включення запису в z-буфер, тут вкл/вимк.
- : fog (false) - відключає освітлення текстури та включає для неї FOG DirectX.
- : emissive (true) - застосовується у джерелах освітлення.
- : distort ( true ) - являє собою механізм спотворень, аналогічний ефекту повітря, що спотворюється в деяких аномаліях, а також "лінза" в головному меню над кнопками.
- : wmark (true) - використовується у валлмарках
- shader : sampler( "s_base" ) - створення буфера приміщення туди текстури. Аргумент є ідентифікатором, що отримується ps і vs шейдерами, де буде фігурувати як predefined-змінна s_base.
Наведені нижче параметри можуть бути лише нижче семплерного рядка!
- : texture (t_base) - поміщення у вище оголошений буфер текстури. Аргумент цієї ф-ції є шлях до текстури, так що цілком можна вказати щось на зразок
: texture ( "fx\fx_sun" )
щоб у буфер встромити текстуру gamedata/textures/fx/fx_sun.dds
Наступні функції встановлюють один із режимів адресації текстури. Режим адресації визначає спосіб обробки текстурних координат при виході за межі діапазону [0.0,1.0]
- : clamp() - режим адресації D3DTADDRESS_CLAMP Значення текстурних координат, що виходять за рамки [0.0,1.0], обрізаються до 0.0 і 1.0 відповідно. Відповідає галці Texture Clamp в СДК.
- : wrap () – режим адресації D3DTADDRESS_WRAP. При виході значень текстурних координат межі [0.0,1.0] від значень віднімається їх ціла частина. Іншими словами, якщо у вас u,v вийшли [1.3, 2.5], у цьому режимі семплювання текстури буде за координатами [0.3, 0.5].
- : mirror () - режим адресації D3DTADDRESS_MIRROR При виході значень текстурних координат за межі [0.0,1.0] від значень віднімається їхня ціла частина і залишок віднімається з 1.0. Якщо u,v вийшли [1.3, 2.6], у цьому режимі семплювання текстури буде за координатами [0.7, 0.4].
Функції встановлення фільтрації текстур:
- : f_none() - точкова фільтрація (тобто по суті, немає фільтрації)
- : f_linear () - лінійна фільтрація
- : f_bilinear () - білінійна фільтрація
- : f_trilinear() - трилінійна фільтрація. На диво непотрібна функція, тому що семплер за замовчуванням створюється з трилінійною фільтрацією
- : f_anisotropic() - анізотропна фільтрація.
Крім цих функцій також є функції для "тонкого" налаштування фільтрації: Налаштування magnification filter
- : fmag_none () - без фільтрації
- : fmag_point () - точкова фільтрація
- : fmag_linear() - лінійна фільтрація
Налаштування minification filter
- : fmin_none () - без фільтрації
- : fmin_point () - точкова фільтрація
- : fmin_linear () - лінійна фільтрація
- : fmin_aniso() - анізотропна фільтрація.
Налаштування mip filter
- : fmip_none () - без фільтрації
- : fmip_point () - точкова фільтрація
- : fmip_linear() - лінійна фільтрація
Різні функції:
- : project() - функція виставляє прапор D3DTTFF_PROJECTED перетворення текстурних координат перед растеризатором. При виставленому прапорі, всі компоненти текстурних координат діляться на w-компоненту. Актуально лише для ffp (R1, ps_1_x).
Також у папці з шейдерами лежать ще файли .s (саме такого імені - точка та ес), які є для всіх *.s-файлів своєрідними заголовними файлами, функції з файлу .s доступні з файлів *.s. На даний момент там є функції printf і закоментовані у другому рендері ф-ції l_point і l_spot, які відповідають за створення точкового та неточкового джерел світла відповідно.