Menggunakan Shader di Direct3D 9

Mengkompilasi Shader untuk Perangkat Keras Tertentu

Shader pertama kali ditambahkan ke Microsoft DirectX di DirectX 8.0. Pada saat itu, beberapa mesin shader virtual didefinisikan, masing-masing kira sesuai dengan prosesor grafis tertentu yang diproduksi oleh vendor grafis 3D teratas. Untuk masing-masing komputer shader virtual ini, bahasa perakitan dirancang. Program yang ditulis ke model shader (nama vs_1_1 dan ps_1_1 - ps_1_4) relatif singkat dan umumnya ditulis oleh pengembang langsung dalam bahasa assembly yang sesuai. Aplikasi ini akan meneruskan kode bahasa perakitan yang dapat dibaca manusia ini ke pustaka D3DX menggunakan D3DXAssembleShader dan mendapatkan kembali representasi biner shader yang pada gilirannya akan diteruskan menggunakan CreateVertexShader atau CreatePixelShader. Untuk detail selengkapnya, lihat kit pengembangan perangkat lunak (SDK).

Situasi di Direct3D 9 serupa. Aplikasi meneruskan shader HLSL ke D3DX menggunakan D3DXCompileShader dan mendapatkan kembali representasi biner dari shader yang dikompilasi yang pada gilirannya diteruskan ke Microsoft Direct3D menggunakan CreatePixelShader atau CreateVertexShader. Runtime tidak tahu apa-apa tentang HLSL, hanya model shader rakitan biner. Ini bagus karena itu berarti bahwa pengkompilasi HLSL dapat diperbarui secara independen dari runtime Direct3D. Anda juga dapat mengkompilasi shader secara offline menggunakan fxc.

Selain pengembangan kompilator HLSL, Direct3D 9 juga memperkenalkan model shader tingkat perakitan untuk mengekspos fungsionalitas perangkat keras grafis generasi terbaru. Pengembang aplikasi dapat bekerja di perakitan untuk model baru ini (vs_2_0, vs_3_0, ps_2_0, ps_3_0) tetapi kami mengharapkan sebagian besar pengembang untuk pindah ke HLSL untuk pengembangan shader.

Tentu saja, kemampuan untuk menulis program HLSL untuk mengekspresikan algoritma bayangan tertentu tidak secara otomatis memungkinkannya untuk berjalan pada perangkat keras tertentu. Aplikasi memanggil D3DX untuk mengkompilasi shader ke dalam kode rakitan biner dengan D3DXCompileShader. Salah satu batasan dengan titik masuk ini adalah parameter yang menentukan model tingkat perakitan mana (atau target kompilasi) yang harus digunakan pengkompilasi HLSL untuk mengekspresikan kode shader akhir. Jika aplikasi melakukan kompilasi shader HLSL pada durasi (dibandingkan dengan waktu kompilasi atau offline), aplikasi dapat memeriksa kemampuan perangkat Direct3D dan memilih target kompilasi yang cocok. Jika algoritma yang dinyatakan dalam shader HLSL terlalu kompleks untuk dijalankan pada target kompilasi yang dipilih, kompilasi akan gagal. Ini berarti bahwa meskipun HLSL adalah manfaat besar untuk pengembangan shader, itu tidak membebaskan pengembang dari realitas pengiriman game ke audiens target dengan perangkat grafis dengan berbagai kemampuan. Sebagai pengembang game, Anda masih harus mengelola pendekatan berjenjang untuk visual Anda; ini berarti menulis shader yang lebih baik untuk kartu grafis yang lebih mampu dan menulis versi yang lebih mendasar untuk kartu yang lebih lama. Namun, dengan HLSL yang ditulis dengan baik, beban ini dapat dikurangi secara signifikan.

Daripada mengkompilasi shader HLSL menggunakan D3DX pada mesin pelanggan pada waktu pemuatan aplikasi atau pada penggunaan pertama, banyak pengembang memilih untuk mengkompilasi shader mereka dari HLSL ke kode perakitan biner sebelum mereka bahkan mengirim. Ini menjauhkan kode sumber HLSL mereka dari mata yang mengintip dan juga memastikan bahwa semua shader yang pernah dijalankan aplikasi mereka telah melalui proses jaminan kualitas internal mereka. Utilitas yang nyaman untuk mengkompilasi shader offline adalah fxc. Alat ini memiliki sejumlah opsi yang dapat Anda gunakan untuk mengkompilasi kode untuk target kompilasi yang ditentukan. Mempelajari output yang dibongkar bisa sangat mendidik selama pengembangan jika Anda ingin mengoptimalkan shader Anda atau hanya umumnya mengenal kemampuan mesin shader virtual pada tingkat yang lebih rinci. Opsi ini dirangkum di bawah ini:

Menginisialisasi Konstanta Shader

Konstanta shader terkandung dalam tabel konstanta. Ini dapat diakses dengan antarmuka ID3DXConstantTable . Variabel shader global dapat diinisialisasi dalam kode shader. Ini diinisialisasi pada waktu proses dengan memanggil SetDefaults.

Mengikat Parameter Shader ke Register Tertentu

Pengkompilasi akan secara otomatis menetapkan register ke variabel global. Pengompilasi akan menetapkan Environment ke sampler register s0, SparkleNoise ke sampler register s1, dan k_s ke register c0 konstan (dengan asumsi tidak ada sampler lain atau register konstanta yang sudah ditetapkan) untuk tiga variabel global berikut:

sampler Environment;
sampler SparkleNoise;
float4 k_s;

Dimungkinkan juga untuk mengikat variabel ke register tertentu. Untuk memaksa pengkompilasi menetapkan ke register tertentu, gunakan sintaks berikut:

register(RegisterName)

di mana RegisterName adalah nama register tertentu. Contoh berikut menunjukkan sintaks penugasan register tertentu, di mana Lingkungan sampler akan terikat ke sampler register s1, SparkleNoise akan terikat ke register sampler s0, dan k_s akan terikat ke register konstan c12:

sampler Environment : register(s1);
sampler SparkleNoise : register(s0);
float4 k_s : register(c12);

Merender Shader yang Dapat Diprogram

Shader dirender dengan mengatur shader saat ini di perangkat, menginisialisasi konstanta shader, memberi tahu perangkat tempat data input yang bervariasi berasal, dan akhirnya merender primitif. Masing-masing dapat dicapai dengan memanggil metode berikut masing-masing:

Penelusuran Kesalahan Shader

Ekstensi DirectX untuk Microsoft Visual Studio .NET menyediakan debugger HLSL terintegrasi penuh dalam Visual Studio .NET Integrated Development Environment (IDE). Untuk mempersiapkan penelusuran kesalahan shader, Anda harus menginstal alat yang tepat di komputer Anda (lihat Debugging Shader di Visual Studio (Direct3D 9)).

Panduan Pemrograman untuk HLSL