Vertex Fog (Direct3D 9)
Ketika sistem melakukan fogging vertex, sistem menerapkan perhitungan kabut di setiap puncak dalam poligon, dan kemudian menginterpolasi hasil di seluruh wajah poligon selama rasterisasi. Efek kabut verteks dihitung oleh mesin pencahayaan dan transformasi Direct3D. Untuk informasi selengkapnya, lihat Parameter Kabut (Direct3D 9).
Jika aplikasi Anda tidak menggunakan Direct3D untuk transformasi dan pencahayaan, aplikasi harus melakukan perhitungan kabut. Dalam hal ini, letakkan faktor kabut yang dihitung dalam komponen alfa dari warna spekular untuk setiap puncak. Anda bebas menggunakan rumus apa pun yang Anda inginkan - berbasis rentang, volumetrik, atau sebaliknya. Direct3D menggunakan faktor kabut yang disediakan untuk menginterpolasi di seluruh wajah setiap poligon. Aplikasi yang melakukan transformasi dan pencahayaan mereka sendiri juga harus melakukan perhitungan kabut vertex mereka sendiri. Akibatnya, aplikasi seperti itu hanya perlu mengaktifkan campuran kabut dan mengatur warna kabut melalui status render terkait, seperti yang dijelaskan dalam Fog Blending (Direct3D 9) dan Fog Color (Direct3D 9).
Catatan
Saat menggunakan shader vertex, Anda harus menggunakan kabut vertex. Ini dicapai dengan menggunakan shader vertex untuk menulis intensitas kabut per-vertex ke register oFog. Setelah shader piksel selesai, data oFog digunakan untuk menginterpolasi secara linier dengan warna kabut. Intensitas ini tidak tersedia dalam shader piksel.
kabut Range-Based
Catatan
Direct3D menggunakan perhitungan kabut berbasis rentang hanya saat menggunakan kabut vertex dengan transformasi Direct3D dan mesin pencahayaan. Ini karena kabut piksel diimplementasikan di driver perangkat, dan saat ini tidak ada perangkat keras untuk mendukung kabut berbasis rentang per piksel. Jika aplikasi Anda melakukan transformasi dan pencahayaannya sendiri, aplikasi harus melakukan perhitungan kabutnya sendiri, berbasis rentang atau sebaliknya.
Terkadang, menggunakan kabut dapat memperkenalkan artefak grafis yang menyebabkan objek dipadukan dengan warna kabut dengan cara nonintuitif. Misalnya, bayangkan adegan di mana ada dua objek yang terlihat: satu cukup jauh untuk dipengaruhi oleh kabut, dan yang lain yang cukup dekat untuk tidak terpengaruh. Jika area tampilan berputar di tempat, efek kabut yang jelas dapat berubah, bahkan jika objek stasioner. Diagram berikut menunjukkan tampilan atas ke bawah dari situasi seperti itu.
Kabut berbasis rentang adalah cara lain, lebih akurat, untuk menentukan efek kabut. Dalam kabut berbasis rentang, Direct3D menggunakan jarak aktual dari sudut pandang ke puncak untuk perhitungan kabutnya. Direct3D meningkatkan efek kabut saat jarak antara dua titik meningkat, daripada kedalaman puncak dalam adegan, sehingga menghindari artefak rotasi.
Jika perangkat saat ini mendukung kabut berbasis rentang, perangkat akan mengatur nilai D3DPRASTERCAPS_FOGRANGE di anggota RasterCaps D3DCAPS9 saat Anda memanggil metode IDirect3DDevice9::GetDeviceCaps . Untuk mengaktifkan kabut berbasis rentang, atur status render D3DRS_RANGEFOGENABLE ke TRUE.
Kabut berbasis rentang dihitung oleh Direct3D selama transformasi dan pencahayaan. Aplikasi yang tidak menggunakan transformasi Direct3D dan mesin pencahayaan juga harus melakukan perhitungan kabut vertex sendiri. Dalam hal ini, berikan faktor kabut berbasis rentang dalam komponen alfa komponen spekular untuk setiap puncak.
Menggunakan Vertex Fog
Gunakan langkah-langkah berikut untuk mengaktifkan kabut vertex di aplikasi Anda.
- Aktifkan fog blending dengan mengatur D3DRS_FOGENABLE ke TRUE.
- Atur warna kabut dalam status render D3DRS_FOGCOLOR.
- Pilih rumus kabut yang diinginkan dengan mengatur status render D3DRS_FOGVERTEXMODE ke anggota jenis enumerasi D3DFOGMODE .
- Atur parameter kabut sesuai keinginan untuk rumus kabut yang dipilih dalam status render.
Contoh berikut, yang ditulis dalam C++, menunjukkan seperti apa langkah-langkah ini dalam kode.
// For brevity, error values in this example are not checked
// after each call. A real-world application should check
// these values appropriately.
//
// For the purposes of this example, g_pDevice is a valid
// pointer to an IDirect3DDevice9 interface.
void SetupVertexFog(DWORD Color, DWORD Mode, BOOL UseRange, FLOAT Density)
{
float Start = 0.5f, // Linear fog distances
End = 0.8f;
// Enable fog blending.
g_pDevice->SetRenderState(D3DRS_FOGENABLE, TRUE);
// Set the fog color.
g_pDevice->SetRenderState(D3DRS_FOGCOLOR, Color);
// Set fog parameters.
if(D3DFOG_LINEAR == Mode)
{
g_pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, Mode);
g_pDevice->SetRenderState(D3DRS_FOGSTART, *(DWORD *)(&Start));
g_pDevice->SetRenderState(D3DRS_FOGEND, *(DWORD *)(&End));
}
else
{
g_pDevice->SetRenderState(D3DRS_FOGVERTEXMODE, Mode);
g_pDevice->SetRenderState(D3DRS_FOGDENSITY, *(DWORD *)(&Density));
}
// Enable range-based fog if desired (only supported for
// vertex fog). For this example, it is assumed that UseRange
// is set to a nonzero value only if the driver exposes the
// D3DPRASTERCAPS_FOGRANGE capability.
// Note: This is slightly more performance intensive
// than non-range-based fog.
if(UseRange)
g_pDevice->SetRenderState(D3DRS_RANGEFOGENABLE, TRUE);
}
Beberapa parameter kabut diperlukan sebagai nilai floating-point, meskipun metode IDirect3DDevice9::SetRenderState hanya menerima nilai DWORD dalam parameter kedua. Contoh ini berhasil memberikan nilai floating-point ke metode ini tanpa terjemahan data dengan mentransmisikan alamat variabel floating-point sebagai penunjuk DWORD, lalu mendereferensikannya.
Topik terkait