Viewports dan Clipping (Direct3D 9)

Secara konseptual, viewport adalah persegi panjang dua dimensi (2D) tempat adegan 3D diproyeksikan. Di Direct3D, persegi panjang ada sebagai koordinat dalam permukaan Direct3D yang digunakan sistem sebagai target penyajian. Transformasi proyeksi mengonversi simpul menjadi sistem koordinat yang digunakan untuk viewport. Viewport juga digunakan untuk menentukan rentang nilai kedalaman pada permukaan target render tempat adegan akan dirender (biasanya 0,0 hingga 1,0).

Frustum Tampilan

Frustum tampilan adalah volume 3D dalam adegan yang diposisikan relatif terhadap kamera viewport. Bentuk volume memengaruhi bagaimana model diproyeksikan dari ruang kamera ke layar. Jenis proyeksi yang paling umum, proyeksi perspektif, bertanggung jawab untuk membuat objek di dekat kamera tampak lebih besar daripada objek di kejauhan. Untuk tampilan perspektif, frustum tampilan dapat divisualisasikan sebagai piramida, dengan kamera diposisikan di ujung seperti yang ditunjukkan pada ilustrasi berikut. Piramida ini berpotongan oleh bidang kliping depan dan belakang. Volume dalam piramida antara bidang kliping depan dan belakang adalah frustum tampilan. Objek hanya terlihat ketika berada dalam volume ini.

illustration of a viewing frustrum with a front and back clipping plan

Jika Anda membayangkan bahwa Anda berdiri di ruangan gelap dan melihat melalui jendela persegi, Anda memvisualisasikan frustum tampilan. Dalam analogi ini, bidang kliping dekat adalah jendela, dan bidang kliping belakang adalah apa pun yang akhirnya mengganggu pandangan Anda - pencakup langit di seberang jalan, pegunungan di kejauhan, atau tidak sama sekali. Anda dapat melihat semua yang ada di dalam piramida terpotong yang dimulai dari jendela dan diakhiri dengan apa pun yang mengganggu pandangan Anda, dan Anda tidak dapat melihat yang lain.

Frustum tampilan didefinisikan oleh fov (bidang tampilan) dan oleh jarak bidang kliping depan dan belakang, yang ditentukan dalam koordinat z, seperti yang ditunjukkan dalam diagram berikut.

diagram of the viewing frustum

Dalam diagram ini, variabel D adalah jarak dari kamera ke asal ruang yang ditentukan di bagian terakhir dari alur geometri - transformasi tampilan. Ini adalah ruang di mana Anda mengatur batas frustum tampilan Anda. Untuk informasi tentang bagaimana variabel D ini digunakan untuk membangun matriks proyeksi, lihat Transformasi Proyeksi (Direct3D 9)

Persegi Panjang Viewport

Anda menentukan persegi panjang viewport di C++ dengan menggunakan struktur D3DVIEWPORT9. Struktur D3DVIEWPORT9 digunakan dengan metode manipulasi viewport berikut yang diekspos oleh antarmuka IDirect3DDevice9.

Struktur D3DVIEWPORT9 berisi empat anggota - X, Y, Lebar, Tinggi - yang menentukan area permukaan target render tempat adegan akan dirender. Nilai-nilai ini sesuai dengan persegi panjang tujuan, atau persegi panjang viewport, seperti yang ditunjukkan dalam diagram berikut.

diagram of the viewport rectangle

Nilai yang Anda tentukan untuk anggota X, Y, Lebar, Tinggi adalah koordinat layar relatif terhadap sudut kiri atas permukaan target render. Struktur mendefinisikan dua anggota tambahan (MinZ dan MaxZ) yang menunjukkan rentang kedalaman tempat adegan akan dirender.

Direct3D mengasumsikan bahwa volume kliping viewport berkisar dari -1,0 hingga 1,0 di X, dan dari 1,0 hingga -1,0 di Y. Ini adalah pengaturan yang paling sering digunakan oleh aplikasi di masa lalu. Anda dapat menyesuaikan rasio aspek viewport sebelum mengklip menggunakan transformasi proyeksi.

Catatan

MinZ dan MaxZ menunjukkan rentang kedalaman tempat adegan akan dirender dan tidak digunakan untuk kliping. Sebagian besar aplikasi akan mengatur anggota ini ke 0.0 dan 1.0 untuk memungkinkan sistem merender ke seluruh rentang nilai kedalaman di buffer kedalaman. Dalam beberapa kasus, Anda dapat mencapai efek khusus dengan menggunakan rentang kedalaman lainnya. Misalnya, untuk merender tampilan heads-up dalam game, Anda dapat mengatur kedua nilai ke 0,0 untuk memaksa sistem merender objek dalam adegan di latar depan, atau Anda dapat mengatur keduanya ke 1,0 untuk merender objek yang harus selalu ada di latar belakang.

 

Dimensi yang digunakan dalam anggota X, Y, Lebar, Tinggi dari struktur D3DVIEWPORT9 untuk viewport menentukan lokasi dan dimensi viewport pada permukaan target render. Nilai-nilai ini berada dalam koordinat layar, relatif terhadap sudut kiri atas permukaan.

Direct3D menggunakan lokasi dan dimensi viewport untuk menskalakan simpul agar sesuai dengan adegan yang dirender ke lokasi yang sesuai pada permukaan target. Secara internal, Direct3D menyisipkan nilai-nilai ini ke dalam matriks berikut yang diterapkan ke setiap puncak.

equation of the matrix that is applied to each vertex

Matriks ini menskalakan simpul sesuai dengan dimensi viewport dan rentang kedalaman yang diinginkan dan menerjemahkannya ke lokasi yang sesuai pada permukaan target render. Matriks juga membalik koordinat y untuk mencerminkan asal layar di sudut kiri atas dengan y meningkat ke bawah. Setelah matriks ini diterapkan, simpul masih homogen - artinya, mereka masih ada sebagai simpul [x,y,z,w]- dan harus dikonversi ke koordinat non-homogen sebelum dikirim ke rasterizer.

Catatan

Matriks penskalaan viewport menggabungkan anggota MinZ dan MaxZ dari struktur D3DVIEWPORT9 untuk menskalakan simpul agar sesuai dengan rentang kedalaman [MinZ, MaxZ]. Ini mewakili semantik yang berbeda dari rilis DirectX sebelumnya, di mana anggota ini digunakan untuk kliping.

 

Catatan

Aplikasi biasanya mengatur MinZ dan MaxZ masing-masing ke 0.0 dan 1.0 untuk menyebabkan sistem merender ke seluruh rentang kedalaman. Namun, Anda dapat menggunakan nilai lain untuk mencapai pengaruh tertentu. Misalnya, Anda dapat mengatur kedua nilai ke 0,0 untuk memaksa semua objek ke latar depan, atau mengatur keduanya ke 1,0 untuk merender semua objek ke latar belakang.

 

Menghapus Viewport

Menghapus viewport mengatur ulang konten persegi panjang viewport pada permukaan target render. Ini juga dapat membersihkan persegi panjang di permukaan buffer kedalaman dan stensil.

Gunakan IDirect3DDevice9::Clear untuk menghapus viewport. Metode ini menerima satu atau beberapa persegi panjang yang menentukan area pada permukaan yang dibersihkan. Mengatur parameter Hitung ke 1, dan parameter pRects ke alamat persegi panjang tunggal yang mencakup seluruh area viewport akan menghapus seluruh viewport. Cara lain untuk menghapus seluruh viewport adalah dengan mengatur parameter pRects ke NULL dan parameter Count ke 0.

IDirect3DDevice9::Clear dapat digunakan untuk membersihkan bit stensil dalam buffer kedalaman. Cukup atur parameter Bendera untuk menentukan cara kerja IDirect3DDevice9::Clear dengan target render dan buffer kedalaman atau stensil terkait. Bendera D3DCLEAR_TARGET akan menghapus viewport menggunakan warna RGBA sewenang-wenang yang Anda berikan dalam argumen Warna (ini bukan warna material). Bendera D3DCLEAR_ZBUFFER akan menghapus buffer kedalaman ke kedalaman arbitrer yang Anda tentukan di Z: 0,0 adalah jarak terdekat, dan 1,0 adalah yang terjauh. Bendera D3DCLEAR_STENCIL akan mengatur ulang bit stensil ke nilai yang Anda berikan dalam argumen Stensil. Anda dapat menggunakan bilangan bulat yang berkisar antara 0 hingga 2n-1, di mana n adalah kedalaman bit buffer stensil.

Dalam beberapa situasi, Anda mungkin hanya merender sebagian kecil dari target render dan permukaan buffer kedalaman. Metode yang jelas juga memungkinkan Anda untuk menghapus beberapa area permukaan Anda dalam satu panggilan. Lakukan ini dengan mengatur parameter Hitung ke jumlah persegi panjang yang ingin Anda kosongkan, dan tentukan alamat persegi panjang pertama dalam array persegi panjang dalam parameter pRects.

Menyiapkan Viewport untuk Kliping

Hasil matriks proyeksi menentukan volume kliping dalam ruang proyeksi sebagai:

-wc<= xc<= wc

-wc<= yc<= wc

0 <= zc<= wc

Di mana: x, y, z, dan w mewakili koordinat puncak setelah transformasi proyeksi diterapkan. Simpul apa pun yang memiliki komponen x, y-, atau z di luar rentang ini diklip, jika kliping diaktifkan (perilaku default).

Dengan pengecualian buffer vertex, aplikasi mengaktifkan atau menonaktifkan kliping dengan cara status render D3DRS_CLIPPING. Informasi kliping untuk buffer vertex dihasilkan selama pemrosesan. Untuk informasi selengkapnya, lihat Pemrosesan Verteks Fungsi Tetap (Direct3D 9) dan Pemrosesan Verteks yang Dapat Diprogram (Direct3D 9).

Direct3D tidak mengklip simpul yang diubah primitif dari buffer vertex kecuali berasal dari IDirect3DDevice9::P rocessVertices. Jika Anda melakukan transformasi Anda sendiri dan memerlukan Direct3D untuk melakukan kliping, Anda tidak boleh menggunakan buffer vertex. Dalam hal ini, aplikasi melintasi data untuk mengubahnya. Direct3D melintasi data untuk kedua kalinya untuk mengklipnya, lalu driver merender data, yang tidak efisien. Jadi, jika aplikasi mengubah data, juga harus mengklip data.

Ketika perangkat menerima simpul pra-transformasi dan menyala (simpul T&L) yang perlu diklip, untuk melakukan operasi kliping, simpul diubah kembali ke ruang kliping menggunakan homogen timbal balik vertex w (RHW) dan informasi viewport. Kliping kemudian dilakukan. Tidak semua perangkat mampu melakukan transformasi balik ini untuk mengklip simpul T&L.

Kemampuan perangkat D3DPMISCCAPS_CLIPTLVERTS menunjukkan apakah perangkat mampu mengklip simpul T&L. Jika kemampuan ini tidak diatur, aplikasi bertanggung jawab untuk mengklip simpul T&L yang ingin dikirim ke perangkat yang akan dirender. Perangkat selalu mampu mengklip simpul T&L dalam mode pemrosesan vertex perangkat lunak (terlepas dari apakah perangkat dibuat dalam mode pemrosesan vertex perangkat lunak, atau beralih ke mode pemrosesan vertex perangkat lunak).

Satu-satunya persyaratan untuk mengonfigurasi parameter viewport untuk perangkat rendering adalah mengatur volume kliping viewport. Untuk melakukan ini, Anda menginisialisasi dan mengatur nilai kliping untuk volume kliping dan untuk permukaan target render. Viewports biasanya disiapkan untuk dirender ke area lengkap permukaan target render, tetapi ini bukan persyaratan.

Anda dapat menggunakan pengaturan berikut untuk anggota struktur D3DVIEWPORT9 untuk mencapainya di C++.

D3DVIEWPORT9 viewData = { 0, 0, width, height, 0.0f, 1.0f };

Setelah mengatur nilai dalam struktur D3DVIEWPORT9, terapkan parameter viewport ke perangkat dengan memanggil metode IDirect3DDevice9::SetViewport. Contoh kode berikut menunjukkan seperti apa panggilan ini.

HRESULT hr;

hr = pd3dDevice->SetViewport(&viewData);
if(FAILED(hr))
    return hr;

Jika panggilan berhasil, parameter viewport diatur dan akan berlaku saat berikutnya metode penyajian dipanggil. Untuk membuat perubahan pada parameter viewport, cukup perbarui nilai dalam struktur D3DVIEWPORT9 dan panggil IDirect3DDevice9::SetViewport lagi.

Catatan

Anggota struktur D3DVIEWPORT9 MinZ dan MaxZ menunjukkan rentang kedalaman tempat adegan akan dirender dan tidak digunakan untuk kliping. Sebagian besar aplikasi mengatur anggota ini ke 0.0 dan 1.0 untuk memungkinkan sistem merender ke seluruh rentang nilai kedalaman di buffer kedalaman. Dalam beberapa kasus, Anda dapat mencapai efek khusus dengan menggunakan rentang kedalaman lainnya. Misalnya, untuk merender tampilan heads-up dalam game, Anda dapat mengatur kedua nilai ke 0,0 untuk memaksa sistem merender objek dalam adegan di latar depan, atau Anda dapat mengatur keduanya ke 1,0 untuk merender objek yang harus selalu ada di latar belakang.

 

Memulai