Shader (шејдер) — то је програм који се извршава на GPU за обраду графичких података: темена, фрагмената или рачунских задатака. За разлику од обичног кода на CPU, шејдер ради паралелно на стотинама језгара, обрађујући сваки елемент независно. Према подацима Khronos Group (2025), шејдери се користе у 100% модерних 3D апликација — од мобилних игара до UI ефеката у системским апликацијама. Програмери пишу шејдере на специјализованим језицима: GLSL, HLSL, Metal Shading Language или SPIR-V.
Главно
Shader — то је мали програм, написан на специјализованом језику и извршен на GPU. Сваки шејдер обрађује један елемент података — теме, фрагмент (пиксел) или радни елемент — независно од других. Паралелизам GPU омогућава покретање хиљада инстанци шејдера истовремено.
Термин је увео Pixar 1980-их за описивање програма који управљају изгледом површина у RenderMan-у. У реалном времену шејдери су се појавили са NVIDIA GeForce 3 (2001) — првом графичком картицом са програмибилним конвејером. Пре шејдера, графика се подешавала кроз фиксне параметре: боју, текстуру, режим мешања.
Према подацима Unity Technologies (2025), просечна мобилна игра користи 50–200 шејдера. Сваки шејдер има варијанте (variants) за различите платформе, нивое квалитета и конфигурације осветљења. Број варијанти може достићи 10 000 по пројекту.
Архитектура шејдера дели се на улазне податке (атрибути, uniform променљиве, текстуре), програмски код и излазне податке (боја, позиција). Uniform променљиве се постављају из CPU пре покретања шејдера и непромењиве су за све елементе кадра. Атрибути су подаци по елементу (координате темена, нормала, UV координате).
SIMT (Single Instruction, Multiple Threads) — модел извршавања шејдера на GPU. Једна инструкција се учитава једном, а извршава се стотинама нити над различитим подацима. На пример, Fragment Shader за 1000 пиксела покреће 1000 нити са истим кодом, али свака нит добија своје UV координате и интерполиране атрибуте.
Важна последица SIMT: гранања у шејдерима су скупа. Ако унутар if блока половина нити иде једном граном, а половина другом, GPU извршава обе гране секвенцијално за све нити. Перформансе падају до 50%. Избегавајте динамичка гранања у шејдерима или их минимизирајте кроз претходне прорачуне на CPU.
Модерни GPU подржавају неколико типова шејдера, сваки за своју фазу графичког или рачунског конвејера. Размотримо основне врсте: теменске, фрагментне, compute и модерне mesh-шејдере.
| Тип шејдера | Фаза конвејера | Обрађује | Језик |
|---|---|---|---|
| Vertex Shader | Теменски | Свако теме | GLSL, HLSL |
| Fragment Shader | Фрагментни | Сваки пиксел | GLSL, HLSL |
| Compute Shader | Рачунски | Произвољни подаци | GLSL, HLSL |
| Geometry Shader | Геометријски | Примитиви | GLSL, HLSL |
| Tessellation Shader | Теселација | Печови | GLSL, HLSL |
| Mesh Shader | Mesh конвејер | Task + Mesh | HLSL, MSL |
Vertex Shader обрађује свако теме геометрије: трансформише координате, израчунава осветљење, преноси податке фрагментном шејдеру. Ово је обавезна фаза графичког конвејера — без ње темена неће стићи на екран. Vertex Shader се позива за свако теме сваког кадра.
Fragment Shader (или Pixel Shader) — најзахтевнија фаза по ресурсима. Он израчунава коначну боју сваког фрагмента, користећи текстуре, осветљење и материјал. Fragment Shader се извршава за сваки пиксел покривен геометријом, узимајући у обзир све нанете текстуре и ефекте. Оптимизација овог шејдера даје највећи пораст перформанси.
Compute Shader — универзални шејдер за произвољне прорачуне на GPU. За разлику од графичких шејдера, није везан за геометрију или пикселе. Compute Shader ради са произвољним баферима података кроз радне групе. Користи се за физику, симулацију честица, пост-ефекте и инференцу неуронских мрежа.
Mesh Shader — најновији тип шејдера, који се појавио у NVIDIA Turing (2018) и Metal 3. Mesh Shader замењује теменски, геометријски и теселациони шејдер једним mesh конвејером. Ради у пару са Task Shader: Task Shader одлучује које mesh групе приказати, Mesh Shader генерише геометрију у лету.
Шејдери се пишу на специјализованим језицима који се компајлирају у машински код GPU. Избор језика зависи од платформе и API-ја. Размотримо главне језике: GLSL, HLSL, Metal Shading Language и посредни формат SPIR-V.
GLSL — језик шејдера за OpenGL, OpenGL ES и WebGL. Синтакса је заснована на C-у са додатком векторских типова (vec2, vec4, mat4) и уграђених функција (texture, normalize, reflect). GLSL ES — верзија за мобилне уређаје са ограниченом прецизношћу (lowp, mediump, highp). Према подацима Khronos (2025), GLSL остаје најраспрострањенији језик шејдера захваљујући cross-платформскости.
#version 300 es
precision mediump float;
in vec2 v_texCoord;
uniform sampler2D u_texture;
out vec4 fragColor;
void main() {
fragColor = texture(u_texture, v_texCoord);
}
Једноставан фрагментни шејдер чита боју из текстуре по UV координатама. precision mediump наводи GPU да користи полупрецизност за float — убрзава извршење на мобилним уређајима за 25–40%.
HLSL — језик шејдера од Microsoft-а за DirectX. Синтакса је ближа C++-у са подршком за класе, структуре и шаблоне. HLSL се користи у Windows апликацијама и кроз Shader Model 6.7+ подржава Ray Tracing, Mesh Shaders и Sampler Feedback. За мобилни развој HLSL се не користи директно, али се компајлира у SPIR-V за Vulkan.
MSL (Metal Shading Language) — језик шејдера компаније Apple, заснован на C++14. За разлику од GLSL и HLSL, MSL се компајлира заједно са апликацијом, што елиминише JIT компајлацију на уређају. MSL подржава показиваче, шаблоне и стандардну библиотеку C++-а. Користи се на свим Apple уређајима: iPhone, iPad, Mac, Apple TV.
#include <metal_stdlib>
using namespace metal;
struct VertexOut {
float4 position [[position]];
float2 texCoord;
};
fragment float4
myFragment(VertexOut in [[stage_in]],
texture2d<float> tex [[texture(0)]]) {
constexpr sampler s = sampler(filter::linear);
return tex.sample(s, in.texCoord);
}
MSL користи атрибуте [[position]], [[stage_in]] и [[texture(N)]] за повезивање ресурса. Компајлер компаније Apple генерише оптимизовани код за тренутни GPU, узимајући у обзир број регистара и кеша.
SPIR-V — посредни бинарни формат шејдера, стандард за Vulkan. Шејдери се пишу на GLSL или HLSL, компајлирају у SPIR-V и учитавају у Vulkan апликацију. SPIR-V није везан за одређени језик — постоје компајлери из Rust, Python, OpenCL C у SPIR-V.
Шејдери на мобилним платформама имају ограничења у поређењу са десктопским: мање регистара, ограничена прецизност и недостатак подршке за неке инструкције. Размотримо специфику шејдера на Android (Vulkan/OpenGL ES) и iOS (Metal).
Android користи GLSL ES за OpenGL и SPIR-V за Vulkan. OpenGL ES 3.2 подржава шејдере са подразумеваном mediump прецизношћу. Vulkan захтева експлицитну компајлацију GLSL у SPIR-V путем glslangValidator-а. На Android-у шејдери се учитавају из текстуалних ресурса или из компајлираних SPIR-V датотека.
Qualcomm Adreno GPU оптимизује шејдере на нивоу драјвера. Препоруке: користите mediump за боју и UV, highp само за позиције; избегавајте текстурна очитавања у теменским шејдерима; групишите прорачуне у векторе (vec4 уместо 4x float). Према подацима Qualcomm (2025), ове оптимизације дају пораст од 30–50%.
iOS користи искључиво Metal Shading Language. Шејдери се компајлирају у машински код заједно са апликацијом путем Xcode-а. Metal пружа Shader Debugger и GPU Capture за профилисање шејдера. Apple GPU (TBDR) има специфичне оптимизације: early fragment test, memoryless render targets и програмибилно мешање.
Према подацима Apple WWDC 2024, за iOS шејдере је критично користити half уместо float, ограничити регистарски притисак (макс 64 регистра) и избегавати зависна текстурна очитавања. iOS шејдери треба да буду компактни — оптимална величина 50–100 ALU инструкција.
Погони игара Unity и Unreal Engine пружају визуелне едиторе шејдера (Shader Graph, Material Editor) и апстрактне језике (ShaderLab, USF). Програмер пише шејдер на високом нивоу, а погон га компајлира за циљну платформу. Unity користи HLSL као посредни језик, Unreal — USF (Unreal Shader Format).
Оптимизација шејдера — кључна фаза развоја графике за мобилне уређаје. Лоше написан шејдер може смањити FPS са 60 на 20. Размотримо основна правила и технике оптимизације.
Користите минималну довољну прецизност: lowp за боју и UV, mediump за нормале и осветљење, highp само за позиције и матрице. Према подацима ARM (2025), mediump операције су 2 пута брже од highp на Mali GPU. У GLSL ES ово се поставља кроз precision квалификаторе.
Текстурна очитавања — најскупља операција у шејдеру (10–30 циклуса наспрам 1–2 за ALU инструкцију). Смањите број очитавања: обједините текстуре у атласе, користите складиштење у uniform низовима уместо текстура, кеширајте резултате суседних пиксела кроз derivative инструкције.
Динамичка гранања (if са uniform променљивом) смањују перформансе SIMT конвејера. Замењујте гранања математичким функцијама: mix(), step(), smoothstep() и clamp(). Ове функције се извршавају у 1–2 инструкције, док гранање може коштати 8–16 инструкција због дивергенције нити.
// Лоше: динамичко гранање у шејдеру
if (u_enableLight) {
color *= computeLighting(normal);
}
// Добро: математичка замена гранања
color *= mix(1.0, computeLighting(normal),
float(u_enableLight));
mix() врши линеарну интерполацију између две вредности. Када је u_enableLight=0, враћа се 1.0 — боја се не мења. Када је u_enableLight=1, враћа се резултат осветљења. Без гранања — све нити извршавају исти код.
Размотримо практичне примере шејдера за мобилни развој — од једноставног сенчења до процедуралног генерисања текстура. Сваки пример демонстрира одређену технику.
Phong модел — класични модел осветљења са дифузном и рефлектујућом компонентом. Vertex Shader израчунава осветљење за свако теме, Fragment Shader само интерполира резултат (Gouraud shading). Погодан за мобилне уређаје због ниске цене.
#version 300 es
layout(location = 0) in vec4 a_position;
layout(location = 1) in vec3 a_normal;
uniform mat4 u_mvp;
uniform mat4 u_modelView;
out vec3 v_color;
void main() {
vec3 normal = normalize(mat3(u_modelView) * a_normal);
vec3 lightDir = normalize(vec3(0.0, 1.0, 1.0));
float diff = max(dot(normal, lightDir), 0.0);
v_color = vec3(0.8, 0.2, 0.2) * (0.3 + diff * 0.7);
gl_Position = u_mvp * a_position;
}
Шејдер израчунава diffuse осветљење: скаларни производ нормале и смера светлости. Резултат се меша са ambient (0.3) и diffuse (0.7) компонентама. Извршава 10–15 ALU инструкција по темену — прихватљиво за 100 000 полигона при 60 FPS на мобилном GPU.
Процедуралне текстуре се генеришу у Fragment Shader-у без учитавања из датотеке. Штеди видео меморију и поједностављује анимацију. Пример — шаховска табла са променљивом величином ћелија. Само неколико ALU инструкција — минимално оптерећење GPU.
#version 300 es
precision mediump float;
in vec2 v_uv;
uniform float u_cells;
out vec4 fragColor;
void main() {
vec2 cell = floor(v_uv * u_cells);
float isWhite = mod(cell.x + cell.y, 2.0);
fragColor = mix(vec4(0.1, 0.1, 0.1, 1.0),
vec4(0.9, 0.9, 0.9, 1.0),
isWhite);
}
8 ALU инструкција — идеалан шејдер за мобилне уређаје. u_cells поставља број ћелија по оси. floor и mod — јефтине операције, извршавају се у 1 циклусу на свим мобилним GPU.
Често постављана питања
Shader се извршава на GPU у SIMT режиму — једна инструкција за стотине нити. Обичан програм на C++ — на CPU у MIMD режиму. Шејдер нема приступ систему датотека, улазу/излазу и динамичкој меморији. Он прима податке кроз бафере и текстуре и враћа позицију или боју.
GLSL — за OpenGL ES и WebGL, cross-платформски. Metal Shading Language — за iOS. HLSL — основа за Unity и Unreal Engine. Почните са GLSL — разумевање основа преноси се на било који језик шејдера.
Главни разлози: висока прецизност (highp уместо mediump), прекомерна текстурна очитавања, динамичка гранања и прекорачење регистарског лимита. Користите RenderDoc или Xcode GPU Frame Debugger за анализу шејдера.
Compute Shader — шејдер за произвољне прорачуне на GPU: физика честица, обрада слика, симулација тканина. За разлику од Fragment Shader-а, није везан за пикселе и може писати у произвољне бафере.
Да, кроз визуелне едиторе: Shader Graph у Unity, Material Editor у Unreal Engine или Metal Shader Converter. Они генеришу шејдерски код на основу нодовне шеме. За дубоку оптимизацију биће потребно разумевање језика шејдера.
Закључци
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође