Shader (shader) — adalah program yang dijalankan pada GPU untuk memproses data grafis: vertex, fragmen, atau tugas komputasi. Berbeda dengan kode biasa pada CPU, shader bekerja secara paralel pada ratusan inti, memproses setiap elemen secara independen. Menurut data Khronos Group (2025), shader digunakan dalam 100% aplikasi 3D modern — dari game mobile hingga efek UI dalam aplikasi sistem. Pengembang menulis shader dalam bahasa khusus: GLSL, HLSL, Metal Shading Language atau SPIR-V.
Poin Utama
Shader — adalah program kecil yang ditulis dalam bahasa khusus dan dijalankan pada GPU. Setiap shader memproses satu elemen data — vertex, fragmen (piksel) atau elemen kerja — secara independen dari yang lain. Paralelisme GPU memungkinkan menjalankan ribuan instance shader secara bersamaan.
Istilah ini diperkenalkan oleh Pixar pada tahun 1980-an untuk menggambarkan program yang mengontrol tampilan permukaan di RenderMan. Secara real-time, shader muncul dengan NVIDIA GeForce 3 (2001) — kartu grafis pertama dengan pipeline yang dapat diprogram. Sebelum shader, grafis dikonfigurasi melalui parameter tetap: warna, tekstur, mode pencampuran.
Menurut data Unity Technologies (2025), game mobile rata-rata menggunakan 50–200 shader. Setiap shader memiliki varian (variants) untuk platform berbeda, tingkat kualitas, dan konfigurasi pencahayaan. Jumlah varian bisa mencapai 10.000 per proyek.
Arsitektur shader dibagi menjadi data masukan (atribut, variabel uniform, tekstur), kode program dan data keluaran (warna, posisi). Variabel uniform diatur dari CPU sebelum shader dijalankan dan tidak berubah untuk semua elemen frame. Atribut adalah data per elemen (koordinat vertex, normal, koordinat UV).
SIMT (Single Instruction, Multiple Threads) — model eksekusi shader pada GPU. Satu instruksi dimuat sekali, tetapi dijalankan oleh ratusan thread pada data yang berbeda. Misalnya, Fragment Shader untuk 1000 piksel menjalankan 1000 thread dengan kode yang sama, tetapi setiap thread menerima koordinat UV dan atribut terinterpolasi sendiri.
Konsekuensi penting dari SIMT: percabangan dalam shader mahal. Jika di dalam blok if setengah thread mengikuti satu cabang dan setengah lainnya mengikuti cabang lain, GPU mengeksekusi kedua cabang secara berurutan untuk semua thread. Performa turun hingga 50%. Hindari percabangan dinamis dalam shader atau minimalkan melalui perhitungan awal pada CPU.
GPU modern mendukung beberapa jenis shader, masing-masing untuk tahap pipeline grafis atau komputasi tertentu. Mari kita bahas jenis utama: vertex, fragment, compute dan mesh-shader modern.
| Jenis shader | Tahap pipeline | Memproses | Bahasa |
|---|---|---|---|
| Vertex Shader | Vertex | Setiap vertex | GLSL, HLSL |
| Fragment Shader | Fragment | Setiap piksel | GLSL, HLSL |
| Compute Shader | Komputasi | Data arbitrer | GLSL, HLSL |
| Geometry Shader | Geometri | Primitif | GLSL, HLSL |
| Tessellation Shader | Tessellation | Patch | GLSL, HLSL |
| Mesh Shader | Pipeline Mesh | Task + Mesh | HLSL, MSL |
Vertex Shader memproses setiap vertex geometri: mentransformasi koordinat, menghitung pencahayaan, mengirim data ke fragment shader. Ini adalah tahap wajib pipeline grafis — tanpanya vertex tidak akan sampai ke layar. Vertex Shader dipanggil untuk setiap vertex setiap frame.
Fragment Shader (atau Pixel Shader) — tahap paling intensif sumber daya. Ia menghitung warna akhir setiap fragmen menggunakan tekstur, pencahayaan dan material. Fragment Shader dijalankan untuk setiap piksel yang tertutup geometri, dengan mempertimbangkan semua tekstur dan efek yang diterapkan. Optimasi shader ini memberikan peningkatan performa terbesar.
Compute Shader — shader universal untuk komputasi arbitrer pada GPU. Berbeda dengan shader grafis, ia tidak terikat pada geometri atau piksel. Compute Shader bekerja dengan buffer data arbitrer melalui grup kerja. Digunakan untuk fisika, simulasi partikel, pasca-efek dan inferensi jaringan saraf.
Mesh Shader — jenis shader terbaru, muncul di NVIDIA Turing (2018) dan Metal 3. Mesh Shader menggantikan shader vertex, geometri dan tessellation dengan satu pipeline mesh. Bekerja bersama Task Shader: Task Shader memutuskan grup mesh mana yang akan di-render, Mesh Shader menghasilkan geometri dengan cepat.
Shader ditulis dalam bahasa khusus yang dikompilasi ke kode mesin GPU. Pilihan bahasa tergantung pada platform dan API. Mari kita bahas bahasa utama: GLSL, HLSL, Metal Shading Language dan format perantara SPIR-V.
GLSL — bahasa shader untuk OpenGL, OpenGL ES dan WebGL. Sintaksis berbasis C dengan penambahan tipe vektor (vec2, vec4, mat4) dan fungsi bawaan (texture, normalize, reflect). GLSL ES — versi untuk perangkat mobile dengan presisi terbatas (lowp, mediump, highp). Menurut data Khronos (2025), GLSL tetap menjadi bahasa shader paling luas berkat kemampuannya lintas platform.
#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);
}
Fragment shader sederhana membaca warna dari tekstur berdasarkan koordinat UV. precision mediump memerintahkan GPU menggunakan setengah presisi untuk float — mempercepat eksekusi pada perangkat mobile sebesar 25–40%.
HLSL — bahasa shader dari Microsoft untuk DirectX. Sintaksis lebih dekat ke C++ dengan dukungan untuk kelas, struktur dan template. HLSL digunakan dalam aplikasi Windows dan melalui Shader Model 6.7+ mendukung Ray Tracing, Mesh Shaders dan Sampler Feedback. Untuk pengembangan mobile, HLSL tidak digunakan langsung, tetapi dikompilasi ke SPIR-V untuk Vulkan.
MSL (Metal Shading Language) — bahasa shader Apple, berbasis C++14. Berbeda dengan GLSL dan HLSL, MSL dikompilasi bersama aplikasi, yang menghilangkan kompilasi JIT pada perangkat. MSL mendukung pointer, template dan pustaka standar C++. Digunakan di semua perangkat 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 menggunakan atribut [[position]], [[stage_in]] dan [[texture(N)]] untuk mengikat sumber daya. Kompilator Apple menghasilkan kode yang dioptimalkan untuk GPU saat ini, mempertimbangkan jumlah register dan cache.
SPIR-V — format biner perantara untuk shader, standar untuk Vulkan. Shader ditulis dalam GLSL atau HLSL, dikompilasi ke SPIR-V dan dimuat ke aplikasi Vulkan. SPIR-V tidak terikat pada bahasa tertentu — ada kompilator dari Rust, Python, OpenCL C ke SPIR-V.
Shader pada platform mobile memiliki keterbatasan dibandingkan desktop: lebih sedikit register, presisi terbatas dan kurangnya dukungan untuk beberapa instruksi. Mari kita bahas spesifik shader pada Android (Vulkan/OpenGL ES) dan iOS (Metal).
Android menggunakan GLSL ES untuk OpenGL dan SPIR-V untuk Vulkan. OpenGL ES 3.2 mendukung shader dengan presisi default mediump. Vulkan memerlukan kompilasi eksplisit GLSL ke SPIR-V melalui glslangValidator. Pada Android, shader dimuat dari sumber daya teks atau dari file SPIR-V yang dikompilasi.
Qualcomm Adreno GPU mengoptimalkan shader pada level driver. Rekomendasi: gunakan mediump untuk warna dan UV, highp hanya untuk posisi; hindari sampling tekstur di vertex shader; kelompokkan perhitungan dalam vektor (vec4 bukan 4x float). Menurut data Qualcomm (2025), optimasi ini memberikan peningkatan 30–50%.
iOS menggunakan secara eksklusif Metal Shading Language. Shader dikompilasi ke kode mesin bersama aplikasi melalui Xcode. Metal menyediakan Shader Debugger dan GPU Capture untuk pembuatan profil shader. Apple GPU (TBDR) memiliki optimasi spesifik: early fragment test, memoryless render targets dan pencampuran yang dapat diprogram.
Menurut data Apple WWDC 2024, untuk shader iOS penting menggunakan half daripada float, membatasi tekanan register (maks 64 register) dan menghindari sampling tekstur dependen. Shader iOS harus kompak — ukuran optimal 50–100 instruksi ALU.
Mesin game Unity dan Unreal Engine menyediakan editor shader visual (Shader Graph, Material Editor) dan bahasa abstrak (ShaderLab, USF). Pengembang menulis shader dalam bahasa tingkat tinggi, dan mesin mengompilasinya untuk platform target. Unity menggunakan HLSL sebagai bahasa perantara, Unreal — USF (Unreal Shader Format).
Optimasi shader — tahap kunci pengembangan grafis untuk perangkat mobile. Shader yang ditulis dengan buruk dapat menurunkan FPS dari 60 menjadi 20. Mari kita bahas aturan dan teknik utama optimasi.
Gunakan presisi minimal yang cukup: lowp untuk warna dan UV, mediump untuk normal dan pencahayaan, highp hanya untuk posisi dan matriks. Menurut data ARM (2025), operasi mediump 2 kali lebih cepat dari highp pada Mali GPU. Dalam GLSL ES ini diatur melalui precision-qualifier.
Sampling tekstur — operasi termahal dalam shader (10–30 siklus dibanding 1–2 untuk instruksi ALU). Kurangi jumlah sampling: gabungkan tekstur dalam atlas, gunakan penyimpanan dalam array uniform sebagai pengganti tekstur, cache hasil piksel tetangga melalui instruksi derivative.
Percabangan dinamis (if dengan variabel uniform) menurunkan performa pipeline SIMT. Ganti percabangan dengan fungsi matematika: mix(), step(), smoothstep() dan clamp(). Fungsi-fungsi ini dijalankan dalam 1–2 instruksi, sementara percabangan bisa menghabiskan 8–16 instruksi karena divergensi thread.
// Buruk: percabangan dinamis dalam shader
if (u_enableLight) {
color *= computeLighting(normal);
}
// Baik: penggantian percabangan matematis
color *= mix(1.0, computeLighting(normal),
float(u_enableLight));
mix() melakukan interpolasi linier antara dua nilai. Ketika u_enableLight=0, dikembalikan 1.0 — warna tidak berubah. Ketika u_enableLight=1, dikembalikan hasil pencahayaan. Tanpa percabangan — semua thread mengeksekusi kode yang sama.
Mari kita bahas contoh praktis shader untuk pengembangan mobile — dari pewarnaan sederhana hingga generasi tekstur prosedural. Setiap contoh mendemonstrasikan teknik tertentu.
Model Phong — model pencahayaan klasik dengan komponen difus dan spekular. Vertex Shader menghitung pencahayaan untuk setiap vertex, Fragment Shader hanya menginterpolasi hasil (Gouraud shading). Cocok untuk perangkat mobile karena biaya rendah.
#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 menghitung pencahayaan diffuse: produk titik dari normal dan arah cahaya. Hasil dicampur dengan komponen ambient (0.3) dan diffuse (0.7). Mengeksekusi 10–15 instruksi ALU per vertex — dapat diterima untuk 100.000 poligon pada 60 FPS di GPU mobile.
Tekstur prosedural dihasilkan dalam Fragment Shader tanpa memuat dari file. Menghemat memori video dan menyederhanakan animasi. Contoh — papan catur dengan ukuran sel yang dapat diubah. Hanya beberapa instruksi ALU — beban minimal pada 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 instruksi ALU — shader ideal untuk perangkat mobile. u_cells menentukan jumlah sel per sumbu. floor dan mod — operasi murah, dijalankan dalam 1 siklus pada semua GPU mobile.
Pertanyaan yang Sering Diajukan
Shader dijalankan pada GPU dalam mode SIMT — satu instruksi untuk ratusan thread. Program C++ biasa — pada CPU dalam mode MIMD. Shader tidak memiliki akses ke sistem file, input/output dan memori dinamis. Ia menerima data melalui buffer dan tekstur dan mengembalikan posisi atau warna.
GLSL — untuk OpenGL ES dan WebGL, lintas platform. Metal Shading Language — untuk iOS. HLSL — dasar untuk Unity dan Unreal Engine. Mulailah dengan GLSL — pemahaman dasar dapat ditransfer ke bahasa shader apa pun.
Penyebab utama: presisi tinggi (highp daripada mediump), sampling tekstur berlebihan, percabangan dinamis dan melampaui batas register. Gunakan RenderDoc atau Xcode GPU Frame Debugger untuk analisis shader.
Compute Shader — shader untuk komputasi arbitrer pada GPU: fisika partikel, pemrosesan gambar, simulasi kain. Berbeda dengan Fragment Shader, tidak terikat pada piksel dan dapat menulis ke buffer arbitrer.
Ya, melalui editor visual: Shader Graph di Unity, Material Editor di Unreal Engine atau Metal Shader Converter. Mereka menghasilkan kode shader berdasarkan diagram node. Untuk optimasi mendalam diperlukan pemahaman bahasa shader.
Kesimpulan
Kami akan mengembangkan aplikasi seluler turnkey
IT Sectr membuat aplikasi iOS dan Android untuk startup dan bisnis sejak 2017. Kami akan memberi saran dan mengusulkan solusi terbaik.
Baca juga