Shader, GPU'da çalıştırılan ve grafik verilerini işleyen bir programdır: köşeler, parçalar veya hesaplama görevleri. CPU'daki normal kodun aksine, shader yüzlerce çekirdekte paralel olarak çalışır ve her öğeyi bağımsız olarak işler. Khronos Group'a (2025) göre shader'lar, mobil oyunlardan sistem uygulamalarındaki UI efektlerine kadar modern 3D uygulamalarının %100'ünde kullanılır. Geliştiriciler shader'ları uzmanlaşmış dillerde yazar: GLSL, HLSL, Metal Shading Language veya SPIR-V.
Önemli noktalar
Shader, uzmanlaşmış bir dilde yazılmış ve GPU'da çalıştırılan küçük bir programdır. Her shader, bir veri öğesini — köşe, parça (piksel) veya iş öğesi — diğerlerinden bağımsız olarak işler. GPU'nun paralelliği, binlerce shader örneğinin aynı anda çalıştırılmasına olanak tanır.
Terim, 1980'lerde Pixar tarafından RenderMan'de yüzeylerin görünümünü kontrol eden programları tanımlamak için tanıtıldı. Gerçek zamanlı shader'lar, programlanabilir boru hattına sahip ilk grafik kartı olan NVIDIA GeForce 3 (2001) ile ortaya çıktı. Shader'lardan önce grafikler sabit parametrelerle yapılandırılıyordu: renk, doku, karıştırma modu.
Unity Technologies'e (2025) göre, ortalama bir mobil oyun 50–200 shader kullanır. Her shader'ın farklı platformlar, kalite seviyeleri ve aydınlatma yapılandırmaları için varyantları vardır. Varyant sayısı proje başına 10.000'e ulaşabilir.
Bir shader'ın mimarisi giriş verileri (nitelikler, uniform değişkenler, dokular), program kodu ve çıkış verileri (renk, konum) olarak ayrılır. Uniform değişkenler, shader yürütülmeden önce CPU tarafından ayarlanır ve karenin tüm öğeleri için değişmez. Nitelikler, öğe başına verilerdir (köşe koordinatları, normal, UV koordinatları).
SIMT (Single Instruction, Multiple Threads), GPU'da shader'ların yürütme modelidir. Bir komut bir kez yüklenir ve farklı veriler üzerinde yüzlerce iş parçacığı tarafından yürütülür. Örneğin, 1000 piksel için bir Fragment Shader, aynı kodla 1000 iş parçacığı çalıştırır, ancak her iş parçacığı kendi UV koordinatlarını ve enterpole edilmiş niteliklerini alır.
SIMT'nin önemli bir sonucu: shader'lardaki dallanmalar pahalıdır. Bir if bloğu içinde iş parçacıklarının yarısı bir dala, diğer yarısı başka bir dala giderse, GPU her iki dalı da tüm iş parçacıkları için sırayla yürütür. Performans %50'ye düşer. Shader'larda dinamik dallanmalardan kaçının veya CPU'da ön hesaplamalarla bunları en aza indirin.
Modern GPU'lar, grafik veya hesaplama boru hattının her aşaması için birden çok shader türünü destekler. Ana türleri inceleyelim: vertex, fragment, compute ve modern mesh shader'lar.
| Shader türü | Boru hattı aşaması | İşlediği | Dil |
|---|---|---|---|
| Vertex Shader | Köşe | Her köşe | GLSL, HLSL |
| Fragment Shader | Parça | Her piksel | GLSL, HLSL |
| Compute Shader | Hesaplama | Rastgele veriler | GLSL, HLSL |
| Geometry Shader | Geometri | İlkeller | GLSL, HLSL |
| Tessellation Shader | Mozaikleme | Yamalar | GLSL, HLSL |
| Mesh Shader | Mesh boru hattı | Task + Mesh | HLSL, MSL |
Vertex Shader, geometrinin her köşesini işler: koordinatları dönüştürür, aydınlatmayı hesaplar, fragment shader'a veri iletir. Bu, grafik boru hattının zorunlu bir aşamasıdır — onsuz köşeler ekrana ulaşmaz. Vertex Shader, her karenin her köşesi için çağrılır.
Fragment Shader (veya Pixel Shader), en çok kaynak tüketen aşamadır. Dokuları, aydınlatmayı ve malzemeyi kullanarak her parçanın son rengini hesaplar. Fragment Shader, uygulanan tüm dokular ve efektler dikkate alınarak geometri tarafından kaplanan her piksel için çalıştırılır. Bu shader'ın optimizasyonu en büyük performans artışını sağlar.
Compute Shader, GPU'da rastgele hesaplamalar için evrensel bir shader'dır. Grafik shader'larının aksine, geometriye veya piksellere bağlı değildir. Compute Shader, çalışma grupları aracılığıyla rastgele veri tamponlarıyla çalışır. Fizik, parçacık simülasyonu, son efektler ve sinir ağı çıkarımı için kullanılır.
Mesh Shader, NVIDIA Turing (2018) ve Metal 3 ile ortaya çıkan en yeni shader türüdür. Mesh Shader, vertex, geometry ve tessellation shader'larını tek bir mesh boru hattıyla değiştirir. Task Shader ile birlikte çalışır: Task Shader hangi mesh gruplarının render edileceğine karar verir ve Mesh Shader anında geometri oluşturur.
Shader'lar, GPU makine koduna derlenen uzmanlaşmış dillerde yazılır. Dil seçimi platforma ve API'ye bağlıdır. Ana dilleri inceleyelim: GLSL, HLSL, Metal Shading Language ve ara format SPIR-V.
GLSL, OpenGL, OpenGL ES ve WebGL için shader dilidir. Sözdizimi C'yi temel alır ve vektör türleri (vec2, vec4, mat4) ile yerleşik işlevler (texture, normalize, reflect) eklenmiştir. GLSL ES, sınırlı hassasiyete sahip mobil cihazlar için sürümdür (lowp, mediump, highp). Khronos'a (2025) göre GLSL, çapraz platform yapısı sayesinde en yaygın shader dili olmaya devam etmektedir.
#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);
}
Basit bir fragment shader, UV koordinatlarından doku rengini okur. precision mediump, GPU'ya float için yarı hassasiyet kullanmasını söyler — mobil cihazlarda yürütmeyi %25–40 oranında hızlandırır.
HLSL, Microsoft'un DirectX için shader dilidir. Sözdizimi C++'a daha yakındır ve sınıfları, yapıları ve şablonları destekler. HLSL, Windows uygulamalarında kullanılır ve Shader Model 6.7+ ile Ray Tracing, Mesh Shaders ve Sampler Feedback'i destekler. Mobil geliştirme için HLSL doğrudan kullanılmaz ancak Vulkan için SPIR-V'ye derlenir.
MSL (Metal Shading Language), Apple'ın C++14 tabanlı shader dilidir. GLSL ve HLSL'nin aksine MSL, uygulamayla birlikte derlenir ve cihazda JIT derlemesini ortadan kaldırır. MSL, işaretçileri, şablonları ve C++ standart kütüphanesini destekler. Tüm Apple cihazlarında kullanılır: 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, kaynakları bağlamak için [[position]], [[stage_in]] ve [[texture(N)]] niteliklerini kullanır. Apple derleyicisi, kayıt sayısını ve önbelleği dikkate alarak mevcut GPU için optimize edilmiş kod oluşturur.
SPIR-V, Vulkan için standart ara ikili shader formatıdır. Shader'lar GLSL veya HLSL ile yazılır, SPIR-V'ye derlenir ve Vulkan uygulamasına yüklenir. SPIR-V belirli bir dile bağlı değildir — Rust, Python, OpenCL C'den SPIR-V'ye derleyiciler mevcuttur.
Mobil platformlarda shader'ların masaüstüne kıyasla sınırlamaları vardır: daha az kayıt, sınırlı hassasiyet ve bazı komutlar için destek eksikliği. Android (Vulkan/OpenGL ES) ve iOS'teki (Metal) shader'ların özelliklerini inceleyelim.
Android, OpenGL için GLSL ES ve Vulkan için SPIR-V kullanır. OpenGL ES 3.2, varsayılan olarak mediump ile shader'ları destekler. Vulkan, glslangValidator aracılığıyla GLSL'den SPIR-V'ye açık derleme gerektirir. Android'de shader'lar dize kaynaklarından veya derlenmiş SPIR-V dosyalarından yüklenir.
Qualcomm Adreno GPU, shader'ları sürücü düzeyinde optimize eder. Öneriler: renk ve UV için mediump kullanın, highp yalnızca konumlar için kullanın; vertex shader'larda doku örneklemesinden kaçının; hesaplamaları vektörler halinde gruplayın (4x float yerine vec4). Qualcomm'a (2025) göre bu optimizasyonlar %30–50 iyileştirme sağlar.
iOS, yalnızca Metal Shading Language kullanır. Shader'lar Xcode aracılığıyla uygulamayla birlikte makine koduna derlenir. Metal, shader'ların profilini çıkarmak için Shader Debugger ve GPU Capture sağlar. Apple GPU (TBDR), early fragment test, memoryless render targets ve programlanabilir karıştırma gibi belirli optimizasyonlara sahiptir.
Apple WWDC 2024'e göre iOS shader'ları için float yerine half kullanmak, kayıt baskısını sınırlamak (maks. 64 kayıt) ve bağımlı doku örneklemelerinden kaçınmak kritik öneme sahiptir. iOS shader'ları kompakt olmalıdır — ideal boyut 50–100 ALU talimatıdır.
Oyun motorları Unity ve Unreal Engine, görsel shader düzenleyicileri (Shader Graph, Material Editor) ve soyut diller (ShaderLab, USF) sağlar. Geliştirici shader'ı üst düzey bir dilde yazar ve motor hedef platform için derler. Unity ara dil olarak HLSL, Unreal ise USF (Unreal Shader Format) kullanır.
Shader optimizasyonu, mobil cihazlar için grafik geliştirmede önemli bir adımdır. Kötü yazılmış bir shader, FPS'yi 60'tan 20'ye düşürebilir. Ana optimizasyon kurallarını ve tekniklerini inceleyelim.
Yeterli minimum hassasiyeti kullanın: renk ve UV için lowp, normaller ve aydınlatma için mediump, yalnızca konumlar ve matrisler için highp. ARM'ye (2025) göre, Mali GPU'larda mediump işlemleri highp'ten 2 kat daha hızlıdır. GLSL ES'de bu, hassasiyet niteleyicileri aracılığıyla ayarlanır.
Doku örneklemesi, bir shader'daki en pahalı işlemdir (ALU talimatı için 1–2 döngüye karşı 10–30 döngü). Örnekleme sayısını azaltın: dokuları atlaslarda birleştirin, dokular yerine uniform dizilerde veri depolayın, türev talimatları aracılığıyla komşu piksellerin sonuçlarını önbelleğe alın.
Dinamik dallanmalar (uniform değişkenli if), SIMT boru hattının performansını düşürür. Dallanmaları matematiksel işlevlerle değiştirin: mix(), step(), smoothstep() ve clamp(). Bu işlevler 1–2 talimatta yürütülürken, bir dallanma iş parçacığı ıraksaması nedeniyle 8–16 talimata mal olabilir.
// Kötü: shader'da dinamik dallanma
if (u_enableLight) {
color *= computeLighting(normal);
}
// İyi: matematiksel dal değiştirme
color *= mix(1.0, computeLighting(normal),
float(u_enableLight));
mix(), iki değer arasında doğrusal enterpolasyon gerçekleştirir. u_enableLight=0 olduğunda 1.0 döndürür — renk değişmez. u_enableLight=1 olduğunda aydınlatma sonucunu döndürür. Dallanma yok — tüm iş parçacıkları aynı kodu yürütür.
Mobil geliştirme için pratik shader örneklerini inceleyelim — basit gölgelemeden prosedürel doku oluşturmaya kadar. Her örnek belirli bir tekniği gösterir.
Phong modeli, yaygın ve yansıtıcı bileşenlere sahip klasik aydınlatma modelidir. Vertex Shader her köşe için aydınlatmayı hesaplar, Fragment Shader yalnızca sonucu enterpole eder (Gouraud gölgelemesi). Düşük maliyeti sayesinde mobil cihazlar için uygundur.
#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;
}
Shader, yaygın aydınlatmayı hesaplar: normal ile ışık yönünün nokta çarpımı. Sonuç, ortam (0.3) ve yaygın (0.7) bileşenleriyle karıştırılır. Köşe başına 10–15 ALU talimatı çalıştırır — mobil GPU'da 60 FPS'de 100.000 çokgen için kabul edilebilir.
Prosedürel dokular, dosyadan yüklenmeden Fragment Shader'da oluşturulur. Video belleğinden tasarruf sağlar ve animasyonu basitleştirir. Örnek — ayarlanabilir hücre boyutuna sahip satranç tahtası. Sadece birkaç ALU talimatı — GPU'da minimum yük.
#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 talimatı — mobil cihazlar için ideal bir shader. u_cells, eksen başına hücre sayısını belirtir. floor ve mod, tüm mobil GPU'larda 1 döngüde yürütülen ucuz işlemlerdir.
Sıkça sorulan sorular
Shader, GPU'da SIMT modunda çalıştırılır — yüzlerce iş parçacığı için tek bir talimat. Normal bir C++ programı, CPU'da MIMD modunda çalışır. Shader'ın dosya sistemine, G/Ç'ye veya dinamik belleğe erişimi yoktur. Verileri tamponlar ve dokular aracılığıyla alır ve bir konum veya renk döndürür.
GLSL — OpenGL ES ve WebGL için, çapraz platform. Metal Shading Language — iOS için. HLSL — Unity ve Unreal Engine'in temeli. GLSL ile başlayın — temellerin anlaşılması herhangi bir shader diline aktarılabilir.
Ana nedenler: yüksek hassasiyet (mediump yerine highp), aşırı doku örneklemesi, dinamik dallanmalar ve kayıt sınırının aşılması. Shader analizi için RenderDoc veya Xcode GPU Frame Debugger kullanın.
Compute Shader, GPU'da rastgele hesaplamalar için bir shader'dır: parçacık fiziği, görüntü işleme, kumaş simülasyonu. Fragment Shader'ın aksine piksellere bağlı değildir ve rastgele tamponlara yazabilir.
Evet, görsel düzenleyiciler aracılığıyla: Unity'de Shader Graph, Unreal Engine'de Material Editor veya Metal Shader Converter. Bunlar, düğüm tabanlı bir şemadan shader kodu oluşturur. Derinlemesine optimizasyon için shader dilinin anlaşılması gerekir.
Özet
Anahtar teslim bir mobil uygulama geliştireceğiz
IT Sectr, 2017'den beri girişimler ve işletmeler için iOS ve Android uygulamaları oluşturmaktadır. Size danışmanlık yapacak ve en iyi çözümü önereceğiz.
Ayrıca okuyun