Transformasi Proyeksi (Direct3D 9)

Anda dapat menganggap transformasi proyeksi sebagai mengontrol internal kamera; dianalogikan dengan memilih lensa untuk kamera. Ini adalah yang paling rumit dari tiga jenis transformasi. Diskusi transformasi proyeksi ini diatur ke dalam topik berikut.

Matriks proyeksi biasanya merupakan proyeksi skala dan perspektif. Transformasi proyeksi mengubah frustum tampilan menjadi bentuk cuboid. Karena ujung dekat frustum tampilan lebih kecil dari ujung jauh, ini memiliki efek memperluas objek yang dekat dengan kamera; ini adalah bagaimana perspektif diterapkan pada adegan.

Dalam frustum tampilan, jarak antara kamera dan asal ruang transformasi tampilan didefinisikan secara semena-mena sebagai D, sehingga matriks proyeksi terlihat seperti ilustrasi berikut.

ilustrasi matriks proyeksi

Matriks tampilan menerjemahkan kamera ke asal dengan menerjemahkan ke arah z oleh - D. Matriks terjemahan seperti ilustrasi berikut.

ilustrasi matriks terjemahan

Mengalikan matriks terjemahan dengan matriks proyeksi (T*P) memberikan matriks proyeksi komposit, seperti yang ditunjukkan dalam ilustrasi berikut.

ilustrasi matriks proyeksi komposit

Transformasi perspektif mengonversi frustum tampilan menjadi ruang koordinat baru. Perhatikan bahwa frustum menjadi cuboid dan juga bahwa asal bergerak dari sudut kanan atas adegan ke tengah, seperti yang ditunjukkan pada diagram berikut.

diagram tentang bagaimana transformasi perspektif mengubah frustum tampilan menjadi ruang koordinat baru

Dalam transformasi perspektif, batas arah x dan y adalah -1 dan 1. Batas arah z adalah 0 untuk bidang depan dan 1 untuk bidang belakang.

Matriks ini menerjemahkan dan menskalakan objek berdasarkan jarak yang ditentukan dari kamera ke bidang kliping dekat, tetapi tidak menganggap bidang pandang (fov), dan nilai-z yang dihasilkannya untuk objek dalam jarak bisa hampir identik, membuat perbandingan kedalaman sulit. Matriks berikut mengatasi masalah ini, dan menyesuaikan simpul untuk memperhitungkan rasio aspek viewport, menjadikannya pilihan yang baik untuk proyeksi perspektif.

ilustrasi matriks untuk proyeksi perspektif

Dalam matriks ini, Zn adalah nilai z dari bidang kliping dekat. Variabel w, h, dan Q memiliki arti berikut. Perhatikan bahwa fovw dan fovk mewakili bidang tampilan horizontal dan vertikal viewport, dalam radian.

persamaan arti variabel

Untuk aplikasi Anda, menggunakan sudut bidang pandang untuk menentukan koefisien penskalaan x dan y mungkin tidak senyaman menggunakan dimensi horizontal dan vertikal viewport (di ruang kamera). Saat matematika berhasil, dua persamaan berikut untuk w dan h menggunakan dimensi viewport, dan setara dengan persamaan sebelumnya.

persamaan makna variabel w dan h

Dalam rumus ini, Zn mewakili posisi bidang kliping dekat, dan variabel Vw dan Vh mewakili lebar dan tinggi viewport, di ruang kamera.

Untuk aplikasi C++, kedua dimensi ini sesuai langsung dengan anggota Lebar dan Tinggi struktur D3DVIEWPORT9 .

Rumus apa pun yang Anda putuskan untuk digunakan, pastikan untuk mengatur Zn ke nilai sebesar mungkin, karena nilai z yang sangat dekat dengan kamera tidak bervariasi. Ini membuat perbandingan mendalam menggunakan z-buffer 16-bit agak rumit.

Seperti halnya dunia dan melihat transformasi, Anda memanggil metode IDirect3DDevice9::SetTransform untuk mengatur transformasi proyeksi.

Menyiapkan Matriks Proyeksi

Fungsi sampel ProjectionMatrix berikut mengatur bidang kliping depan dan belakang, serta bidang sudut pandang horizontal dan vertikal. Bidang tampilan harus kurang dari radian pi.

D3DXMATRIX 
ProjectionMatrix(const float near_plane, // Distance to near clipping 
                                         // plane
                 const float far_plane,  // Distance to far clipping 
                                         // plane
                 const float fov_horiz,  // Horizontal field of view 
                                         // angle, in radians
                 const float fov_vert)   // Vertical field of view 
                                         // angle, in radians
{
    float    h, w, Q;

    w = (float)1/tan(fov_horiz*0.5);  // 1/tan(x) == cot(x)
    h = (float)1/tan(fov_vert*0.5);   // 1/tan(x) == cot(x)
    Q = far_plane/(far_plane - near_plane);

    D3DXMATRIX ret;
    ZeroMemory(&ret, sizeof(ret));

    ret(0, 0) = w;
    ret(1, 1) = h;
    ret(2, 2) = Q;
    ret(3, 2) = -Q*near_plane;
    ret(2, 3) = 1;
    return ret;
}   // End of ProjectionMatrix

Setelah membuat matriks, atur dengan IDirect3DDevice9::SetTransform yang menentukan D3DTS_PROJECTION.

Pustaka utilitas D3DX menyediakan fungsi berikut untuk membantu Anda menyiapkan matriks proyeksi Anda.

Matriks Proyeksi yang Ramah-W

Direct3D dapat menggunakan komponen w dari vertex yang telah diubah oleh matriks dunia, tampilan, dan proyeksi untuk melakukan perhitungan berbasis kedalaman dalam efek buffer kedalaman atau kabut. Komputasi seperti ini mengharuskan matriks proyeksi Anda menormalkan w setara dengan z ruang dunia. Singkatnya, jika matriks proyeksi Anda mencakup koefisien (3,4) yang bukan 1, Anda harus menskalakan semua koefisien dengan inversi koefisien (3,4) untuk membuat matriks yang tepat. Jika Anda tidak memberikan matriks yang sesuai, efek kabut dan buffer kedalaman tidak diterapkan dengan benar.

Ilustrasi berikut menunjukkan matriks proyeksi yang tidak sesuai, dan matriks yang sama diskalakan sehingga kabut relatif mata akan diaktifkan.

ilustrasi matriks proyeksi yang tidak sesuai dan matriks dengan kabut relatif mata

Dalam matriks sebelumnya, semua variabel diasumsikan bukan nol. Untuk informasi selengkapnya tentang kabut mata relatif, lihat Kedalaman Mata Relatif vs. Berbasis Z. Untuk informasi tentang buffering kedalaman berbasis w, lihat Buffer Kedalaman (Direct3D 9).

Direct3D menggunakan matriks proyeksi yang saat ini ditetapkan dalam perhitungan kedalaman berbasis w. Akibatnya, aplikasi harus menetapkan matriks proyeksi yang sesuai untuk menerima fitur berbasis w yang diinginkan, bahkan jika mereka tidak menggunakan Direct3D untuk transformasi.

Transformasi