Tahapan Tessellation

Runtime Direct3D 11 mendukung tiga tahap baru yang mengimplementasikan tessellation, yang mengonversi permukaan subdivisi detail rendah menjadi primitif detail yang lebih tinggi pada GPU. Ubin Tessellation (atau memecah) permukaan urutan tinggi menjadi struktur yang sesuai untuk penyajian.

Dengan menerapkan tesselulasi dalam perangkat keras, alur grafis dapat mengevaluasi model detail yang lebih rendah (jumlah poligon yang lebih rendah) dan merender secara lebih rinci. Meskipun tessellasi perangkat lunak dapat dilakukan, tesselulasi yang diterapkan oleh perangkat keras dapat menghasilkan sejumlah besar detail visual (termasuk dukungan untuk pemetaan perpindahan) tanpa menambahkan detail visual ke ukuran model dan melumpuhkan laju refresh.

Manfaat Tessellation

Tessellation:

  • Menyimpan banyak memori dan bandwidth, yang memungkinkan aplikasi untuk merender permukaan terperinci yang lebih tinggi dari model resolusi rendah. Teknik tessellation yang diterapkan dalam alur Direct3D 11 juga mendukung pemetaan perpindahan, yang dapat menghasilkan sejumlah detail permukaan yang menakjubkan.
  • Mendukung teknik penyajian yang dapat diskalakan, seperti berkelanjutan atau melihat tingkat detail dependen yang dapat dihitung dengan cepat.
  • Meningkatkan performa dengan melakukan komputasi mahal pada frekuensi yang lebih rendah (melakukan perhitungan pada model detail yang lebih rendah). Ini bisa termasuk memadukan perhitungan menggunakan bentuk campuran atau target morf untuk perhitungan animasi atau fisika realistis untuk deteksi tabrakan atau dinamika tubuh lunak.

Alur Direct3D 11 mengimplementasikan tesselulasi dalam perangkat keras, yang melakukan off-load pekerjaan dari CPU ke GPU. Hal ini dapat menyebabkan peningkatan performa yang sangat besar jika aplikasi menerapkan sejumlah besar target morf dan/atau model pengulir/deformasi yang lebih canggih. Untuk mengakses fitur tessellation baru, Anda harus mempelajari tentang beberapa tahap alur baru.

TahapAn Alur Baru

Tessellation menggunakan GPU untuk menghitung permukaan yang lebih rinci dari permukaan yang dibangun dari patch quad, patch segitiga, atau isoline. Untuk memperkirakan permukaan yang diurutkan tinggi, setiap patch dibagi menjadi segitiga, titik, atau garis menggunakan faktor tessellation. Alur Direct3D 11 mengimplementasikan tesselulasi menggunakan tiga tahap alur baru:

  • Tahap Hull-Shader - Tahap shader yang dapat diprogram yang menghasilkan patch geometri (dan konstanta patch) yang sesuai dengan setiap patch input (quad, segitiga, atau garis).
  • Tahap Tessellator - Tahap alur fungsi tetap yang membuat pola pengambilan sampel domain yang mewakili patch geometri dan menghasilkan sekumpulan objek yang lebih kecil (segitiga, titik, atau garis) yang menghubungkan sampel ini.
  • Tahap Domain-Shader - Tahap shader yang dapat diprogram yang menghitung posisi puncak yang sesuai dengan setiap sampel domain.

Diagram berikut menyoroti tahap baru alur Direct3D 11.

diagram alur direct3d 11 yang menyoroti tahapan hull-shader, tessellator, dan domain-shader

Diagram berikut menunjukkan perkembangan melalui tahap tessellation. Perkembangan dimulai dengan permukaan subdivisi detail rendah. Perkembangan berikutnya menyoroti patch input dengan patch geometri, sampel domain, dan segitiga yang sesuai yang menghubungkan sampel ini. Perkembangan akhirnya menyoroti simpul yang sesuai dengan sampel ini.

diagram perkembangan tessellation

Tahap Hull-Shader

Shader lambung -- yang dipanggil sekali per patch -- mengubah titik kontrol input yang menentukan permukaan berurutan rendah menjadi titik kontrol yang membentuk patch. Ini juga melakukan beberapa perhitungan per patch untuk menyediakan data untuk tahap tessellation dan tahap domain. Pada tingkat kotak hitam paling sederhana, tahap lambung-shader akan terlihat seperti diagram berikut.

diagram tahap lambung-shader

Shader lambung diimplementasikan dengan fungsi HLSL, dan memiliki properti berikut:

  • Input shader adalah antara 1 dan 32 titik kontrol.
  • Output shader adalah antara 1 dan 32 titik kontrol, terlepas dari jumlah faktor tessellation. Output titik kontrol dari shader lambung dapat dikonsumsi oleh tahap domain-shader. Data konstanta patch dapat dikonsumsi oleh shader domain; faktor tessellation dapat dikonsumsi oleh shader domain dan tahap tessellation.
  • Faktor tesselulasi menentukan berapa banyak yang harus membantah setiap patch.
  • Shader menyatakan status yang diperlukan oleh tahap tessellator. Ini termasuk informasi seperti jumlah titik kontrol, jenis wajah patch dan jenis partisi yang akan digunakan saat melakukan tessellating. Informasi ini muncul sebagai deklarasi biasanya di bagian depan kode shader.
  • Jika tahap hull-shader mengatur faktor tesselulasi tepi apa pun menjadi = 0 atau NaN, patch akan dimusnahkan. Akibatnya, tahap tessellator mungkin atau mungkin tidak berjalan, shader domain tidak akan berjalan, dan tidak ada output yang terlihat yang akan diproduksi untuk patch tersebut.

Pada tingkat yang lebih dalam, shader lambung benar-benar beroperasi dalam dua fase: fase titik kontrol dan fase konstanta patch, yang dijalankan secara paralel oleh perangkat keras. Pengkompilasi HLSL mengekstrak paralelisme dalam shader lambung dan mengodekannya menjadi bytecode yang mendorong perangkat keras.

  • Fase titik kontrol beroperasi sekali untuk setiap titik kontrol, membaca titik kontrol untuk patch, dan menghasilkan satu titik kontrol output (diidentifikasi oleh ControlPointID).
  • Fase konstanta patch beroperasi sekali per patch untuk menghasilkan faktor tesselulasi tepi dan konstanta per patch lainnya. Secara internal, banyak fase konstanta patch dapat berjalan pada saat yang sama. Fase konstanta patch memiliki akses baca-saja ke semua titik kontrol input dan output.

Berikut adalah contoh shader lambung:

[patchsize(12)]
[patchconstantfunc(MyPatchConstantFunc)]
MyOutPoint main(uint Id : SV_ControlPointID,
     InputPatch<MyInPoint, 12> InPts)
{
     MyOutPoint result;
     
     ...
     
     result = TransformControlPoint( InPts[Id] );

     return result;
}

Untuk contoh yang membuat shader lambung, lihat Cara: Membuat Hull Shader.

Tahap Tessellator

Tessellator adalah tahap fungsi tetap yang diinisialisasi dengan mengikat shader lambung ke alur (lihat Cara: Menginisialisasi Tahap Tessellator). Tujuan dari tahap tesselator adalah untuk membagi domain (quad, tri, atau garis) menjadi banyak objek yang lebih kecil (segitiga, titik atau garis). Tessellator memutihkan domain kanonis dalam sistem koordinat yang dinormalisasi (nol ke satu). Misalnya, domain quad dipesan ke kotak unit.

Tesselator beroperasi sekali per patch menggunakan faktor tessellation (yang menentukan seberapa halus domain akan dipesan) dan jenis partisi (yang menentukan algoritma yang digunakan untuk mengiris patch) yang diteruskan dari tahap hull-shader. Tessellator menghasilkan koordinat uv (dan opsional w) dan topologi permukaan ke tahap domain-shader.

Secara internal, tesselator beroperasi dalam dua fase:

  • Fase pertama memproses faktor tesselulasi, memperbaiki masalah pembulatan, menangani faktor yang sangat kecil, mengurangi dan menggabungkan faktor, menggunakan aritmatika floating-point 32-bit.
  • Fase kedua menghasilkan daftar titik atau topologi berdasarkan jenis partisi yang dipilih. Ini adalah tugas inti dari tahap tessellator dan menggunakan pecahan 16-bit dengan aritmatika titik tetap. Aritmatika titik tetap memungkinkan akselerasi perangkat keras sambil mempertahankan presisi yang dapat diterima. Misalnya, dengan patch lebar 64 meter, presisi ini dapat menempatkan titik pada resolusi 2 mm.
Jenis Partisi Rentang
fractional_odd [1...63]
fractional_even Rentang TessFactor: [2..64]
bilangan bulat Rentang TessFactor: [1..64]
pow2 Rentang TessFactor: [1..64]

Tahap Domain-Shader

Shader domain menghitung posisi puncak dari titik yang dibagi dalam patch output. Shader domain dijalankan sekali per titik output tahap tesselator dan memiliki akses baca-saja ke koordinat UV output tahap tessellator, patch output shader lambung, dan konstanta patch output shader lambung, seperti yang ditunjukkan diagram berikut.

diagram tahap domain-shader

Properti shader domain meliputi:

  • Shader domain dipanggil sekali per koordinat output dari tahap tessellator.
  • Shader domain mengonsumsi titik kontrol output dari tahap hull-shader.
  • Shader domain menghasilkan posisi puncak.
  • Input adalah output shader lambung termasuk titik kontrol, data konstanta patch, dan faktor tesselulasi. Faktor tesselulasi dapat mencakup nilai yang digunakan oleh tesselator fungsi tetap serta nilai mentah (sebelum membulatkan dengan teselelasi bilangan bulat, misalnya), yang memfasilitasi geomorfing, misalnya.

Setelah shader domain selesai, tessellation selesai dan data alur berlanjut ke tahap alur berikutnya (geometry shader, pixel shader dll). Shader geometri yang mengharapkan primitif dengan kedekatan (misalnya, 6 simpul per segitiga) tidak valid ketika tessellation aktif (ini menghasilkan perilaku yang tidak terdefinisi, yang akan dikeluhkan oleh lapisan debug).

Berikut adalah contoh shader domain:

void main( out    MyDSOutput result, 
           float2 myInputUV : SV_DomainPoint, 
           MyDSInput DSInputs,
           OutputPatch<MyOutPoint, 12> ControlPts, 
           MyTessFactors tessFactors)
{
     ...

     result.Position = EvaluateSurfaceUV(ControlPoints, myInputUV);
}

API untuk menginisialisasi Tahapan Tessellation

Tessellation diimplementasikan dengan dua tahap shader baru yang dapat diprogram: shader lambung dan shader domain. Tahapan shader baru ini diprogram dengan kode HLSL yang didefinisikan dalam model shader 5. Target shader baru adalah: hs_5_0 dan ds_5_0. Seperti semua tahap shader yang dapat diprogram, kode untuk perangkat keras diekstraksi dari shader yang dikompilasi yang diteruskan ke runtime ketika shader terikat ke alur menggunakan API seperti DSSetShader dan HSSetShader. Tetapi pertama-tama, shader harus dibuat menggunakan API seperti CreateHullShader dan CreateDomainShader.

Aktifkan tessellation dengan membuat shader lambung dan mengikatnya ke tahap hull-shader (ini secara otomatis menyiapkan tahap tessellator). Untuk menghasilkan posisi puncak akhir dari patch tessellated, Anda juga perlu membuat shader domain dan mengikatnya ke tahap domain-shader. Setelah tessellation diaktifkan, input data ke tahap perakit input harus berupa data patch. Artinya, topologi perakitan input harus berupa topologi konstan patch dari D3D11_PRIMITIVE_TOPOLOGY diatur dengan IASetPrimitiveTopology.

Untuk menonaktifkan tessellation, atur shader lambung dan shader domain ke NULL. Baik tahap geometry-shader maupun tahap stream-output tidak dapat membaca titik kontrol output hull-shader atau data patch.

Caranya:

Dokumentasi ini juga berisi contoh untuk menginisialisasi tahap tessellation.

Item Deskripsi
Cara: Membuat Hull Shader
Buat shader lambung.
Cara: Mendesain Hull Shader
Desain shader lambung.
Cara: Menginisialisasi Tahap Tessellator
Menginisialisasi tahap tessellation.
Cara: Membuat Shader Domain
Membuat shader domain.
Cara: Mendesain Shader Domain
Membuat shader domain.

Alur Grafik