Selasa, 23 Februari 2010  
 
[9/2/2009] GRAFIS 3D: MENAMBAHKAN DETAIL PADA TERRAIN



 

Pada demo aplikasi artikel sebelumnya, gambar terrain terlihat kotak-kotak pada jarak dekat. Kali ini kita akan bahas bagaimana memperbaiki kualitas gambar hasil render. Zamrony P. Juhara

 

BAGIAN 4 DARI 4 ARTIKEL

KITA AKAN membahas beberapa isu terkait detail terrain, yakni bagaimana mengurangi tampilan kotak-kotak yang terlihat ketika posisi berada dekat dengan pengama dan bagaimana menambah variasi detail pada permukaan terrain menggunakan tekstur. Sebelumnya mari kita bahas mengapa terrain terlihat kotak-kotak pada jarak dekat.

Problem Texture Mapping

Kita telah menggunakan tekstur selama artikel-artikel sebelumnya. Tekstur pada demo sebelumnya selalu dipetakan ke seluruhterrain seperti pada Gambar 1.

Jika ukuran tekstur kecil dan dipetakan ke seluruh terrain yangcukup besar, hasilnya terrain tampak kurang realistis karenatekstur terlihat kotak-kotak terutama bila dilihat dari jarak dekat (Gambar 2). Hal ini karena gambar tekstur akan ditarik (stretched) untuk memenuhi mesh terrain.

Solusi yang mudah tentunya memperbesar resolusi gambar tekstur yang dipakai. Namun, cara ini tidak selalu berhasil karena beberapa sebab. Pertama, tidak semua video card mendukung ukuran tekstur yang terlalu besar. Sebagian besar video card, hanya mengizinkan ukuran tekstur maksimal 1024x1024.

Kedua, kebutuhan memory untuk menyimpan tekstur menjadi membengkak. Tekstur tak ter-compress berukuran 1024x1024 dengan kedalaman warna 16 bit membutuhkan 1024x1024x2 byte=2097152 byte=2 MB. Memory video card saat ini mungkin cukup menampung data tekstur tersebut, namun yang perlu disimpan di memory video card tentu bukan hanya satu tekstur   ini saja, Anda tentu membutuhkan memory untuk menyimpan vertex/index buffer, tekstur-tekstur lain yang jumlahnya bisa cukup banyak dan tertampung lagi di memory video card.

Lalu, bagaimana solusinya agar detail tekstur terjaga, tapi tanpa menambah resolusi tekstur?

Pada artikel “Grafi  s 3D: Texture Mapping” di PC Media edisi 07/2007, kita sudah pernah mendiskusikan masalah mode pengalamatan tekstur (texture adressing mode). Texture addressing mode adalah mode yang menentukan bagaimana tekstur di-petakan ke poligon apabila koordinat teksturnya di luar nilai 0.0 hingga 1.0. Ada  empat mode, yakni wrap, border color, clamp, dan mirror. Sekarang kita akan menggunakan pengetahuan tersebut untuk memecahkan problem tersebut.

Untuk menjaga detail tetap terjaga walau terrain dilihat dari jarak dekat, kita harus memetakan tekstur berderet-deret pada terrain (Gambar 3). Ini bisa kita kerjakan dengan menggunakan addressing mode wrap.

Menghitung Koordinat Tekstur

Perhatikan lagi Gambar 3. Koordinat tekstur ditandai sumbu berwarna merah. Untuk menghitung koordinat u, v agar tekstur digambar berderet-deret dari kiri ke kanan dan atas ke bawah (tile), kita hitung berapa nilai increment yang akan kita gunakan menambah koordinat vertex untuk tiap-tiap vertex.  Koordinat tekstur vertex v0 adalah u=0.0, v=4.2, v3 adalah u=4.2, v=4.2, v15 adalah u=4.2, v=0.0 dan v12 di u=0.0, v=0.0. Koordinat tekstur vertex lainnya diperoleh melalui interpolasi berikut:

u=i*u_max/(jumlah vertex horizontal-1)

v=j*v_max/(jumlah vertex vertikal-1)

di mana

i=0,1,2,..,(jumlah vertex horizontal-1)

j=0,1,2,..,(jumlah vertex vertikal-1)

u_max adalah nilai koordinat u terbesar

v_max adalah nilai koordinat v terbesar

Untuk contoh pada Gambar 3, nilai u_max dan v_max adalah 4.2. Implementasi lengkap bagaimana penyusunan koordinat vertex dapat Anda temukan pada metode GenerateVertexArray() pada kelas TBruteForceTerrain. Metode ini dipanggil pada saat vertex buffer dibuat (CreateVertex()). Anda dapat temukan metode ini di fi  le unit uterrain.pas pada CD/DVD.

Mengatur Mode Pengalamatan Tekstur (Texture Addresing Mode)

Langkah selanjutnya adalah mengatur mode pengalamatan tekstur menjadi D3DTADDRESS_WRAP untuk masing-masing koordinat u, v. (Listing 1). Parameter pertama pada metode SetSamplerState() adalah texture stage yang akan diubah.

Gambar 4 berisi perbandingan antara penggunaan mode pengalamatan tekstur tanpa wrap dan dengan wrap. Tampak pada Gambar 4 bagian kiri, detail pada poligon yang terdekat, terlalu rendah sehingga terlihat kotak-kotak. Pada bagian kanan, walau masih terlihat kotak-kotak, poligon yang dekat terlihat lebih detail.

Texture Filtering

Perhatikan Gambar 4. Pada jarak dekat, poligon menempati lebih banyak pixel di layar daripada di tekstur, akibatnya banyak pixel di layar dipetakan pada texel (texture element) yang sama.

Hasilnya adalah tampilan yang tampak kotak-kotak pada jarak dekat. Hal ini biasa disebut magnifi  cation artifact.

Pada jarak jauh, poligon menempati lebih sedikit pixel di layar daripada di tekstur, akibatnya satu pixel harus dipetakan pada beberapa texel yang berbeda. Idealnya, warna pixel dihitung dengan mengambil rata-rata warna beberapa texel yang akan dipetakan. Namun karena perhitungan rata-rata cukup menguras kerja processor, default-nya adalah warna pixel dipilih dari warna salah satu texel yang koordinatnya diambil dari pembulatan. Pemilihan ini sering kali tidak akurat karena texel-texel yang merupakan kontributor utama integritas gambar mungkin tidak terpilih. Hasilnya adalah tampilan yang terlihat berbutir mirip pasir pada poligon di kejauhan (minifi  cation artifact).

Texture filtering digunakan untuk memperbaiki kualitasgambar hasil render dengan mengurangi magnifi  cation dan minification artifact.

Ada beberapa jenis filtering yang disediakan Direct3D. Pointfiltering (D3DTEXF_POINT), bilinear filtering  (D3DTEXF_LINEAR), dan anisotropic filtering (D3DTEXF_ANISOTROPIC).

Point Filtering

Point filtering (kadang disebut juga  nearest point sampling) dikerjakan dengan mengambil pixel pada koordinat UV yang sudah dibulatkan. Jadi bila koordinat UV adalah (10.4, 12.2) maka pixel diambil dari gambar tekstur pada koordinat (10,12).

Koordinat UV tidak langsung dibulatkan melainkan diubah darikoordinat tekstur ke koordinat gambar dengan formula:

 U=u*imageWidth-0.5

V=v*imageHeight-0.5

Di mana u, v adalah koordinat tekstur.

Bilinear Filtering

Setelah koordinat UV yang sudah dibulatkan diperoleh, warna texel saat ini dan empat texel tetangga digabung untuk menghasilkan warna akhir. Bobot warna texel dihitung dengan mempertimbangkan jarak texel terhadap koordinat UV. Sebagian besar video card didesain optimal untuk penggunaan linear filtering.

Anisotropic Filtering

Kata  anisotropic berarti “berbeda bentuk”. Jika filter ini dihidupkan, bentuk fi  lterpada ruang koordinat tekstur dan  jumlah texel yang diambil (sampling) dipengaruhi oleh orientasi poligon. Anisotropic filtering diperlukan untuk menutupi kekuranganbilinear filtering. Bilinear menggunakanfilter berbentuk kotak. Bilinear filtering bagus pada poligon-poligon yang vektornormalnya menghadap ke Anda, namununtuk poligon yang vektor normalnyamenjauhi, akan timbul efek distorsi yang disebut anisotropy.

Menambah Detail dengan Multi-texturing

Teknik berikutnya adalah menggunakan tekstur lebih dari satu untuk dipetakan dan dicampur pada suatu poligon, biasa disebut multi-texturing atau multiple texture blending. Teknik ini biasanya digunakan untuk menghasilkan efek-efek tertentu. Pada terrain rendering, teknik ini digunakan untuk menambah detil pada terrain, terutama yang dekat dengan pengamat (Gambar 6).

Multi-texturing bisa dikerjakan dengan multipass rendering atau dengan memanfaatkan multiple texture stage. Multi-texturing dengan multipass rendering dikerjakan dengan menggambar poligon yang sama lebih dari satu kali dengan tekstur yang berbeda. Teknik ini digunakan pada video card lama.

Contohnya seperti pada Listing 1.

Multipass rendering menurunkan performa keseluruhan, sebanding dengan jumlah rendering pass yang digunakan. Pada video card yang lebih baru, multi-texturing dapat dikerjakan menggunakan texture stage lebih dari satu atau dengan pixel shader yang memungkinkan multi-texturing dikerjakan dalam sekali penggambaran (single pass).

Kita akan bahas texture stage segera, sedangkan multi-texturing dengan pixel shader belum kita bahas.

Saya tidak akan menggunakan teknik multipass rendering pada demo aplikasi yang ada di CD/DVD karena sebagian besar kartu grafis mainstream saat ini umumnya mendukung multi-texturing dengan multiple texture stage.

Texture Stage

Texture stage adalah tingkat-tingkat dalam proses pencampuran tekstur (texture blending). Hasil operasi yang dikerjakan suatu stage dapat menjadi input bagi stage berikutnya (Gambar 7). Jumlah texture stage yang didukung Direct3D adalah 8, namun mungkin jumlahnya bisa lebih kecil tergantung video card.

Anda bisa mengetahuinya dari field MaxTextureBlendStages pada  tipe data D3DCAPS9.

Tiap stage dapat diubah status operasi dan argumen-argu-men yang digunakan (Gambar 8). Ada beberapa operasi yang disediakan, yakni operasi untuk warna dan alpha dan operasi untuk mengatur argumen warna dan argumen alpha.

D3DTSS_COLORARGn, D3DTSS_ALPHAARGn

Operasi D3DTSS_COLORARG0,  D3DTSS_COLORARG1 dan   D3DTSS_COLORARG2 digunakan hanya untuk mengatur argumen-argumen input operasi warna. Sebagian besar operasi warna hanya membutuhkan ARG1 dan ARG2, namun ada beberapa yang butuh ARG0.

Operasi D3DTSS_ALPHAARG0,  D3DTSS_ALPHAARG1 dan  D3DTSS_ALPHAARG2 digunakan hanya untuk mengatur argumen-argumen input operasi alpha. Nilai yang valid untuk ARGn adalah konstan yang berprefiks D3DTA_ (TA singkatan dari Texture Argument) seperti pada Tabel 1.

TABEL 1. ARGUMEN TEKSTUR

NAMA

D3DTA_CONSTANT 

D3DTA_CURRENT 

D3DTA_DIFFUSE 

D3DTA_TEXTURE 

D3DTA_TFACTOR 

D3DTA_SPECULAR 

KETERANGAN

Mengisi argumen ARGn dengan nilai konstan.

Jika digunakan pada stage bukan 0, ARGn akan diisi dengan

hasil output stage sebelumnya. Jika digunakan pada stage

0, sama dengan mengisi ARGn dengan D3DTA_DIFFUSE.

Argumen ARGn diisi dengan warna diffuse terinterpolasi.

Jika kita menggunakan pencahayaan, warna hasil kalkulasi

pencahayaan dimasukkan ke ARGn.

Warna texel disi ke ARGn.

Warna yang ada di render state D3DRS_TEXTUREFACTOR

digunakan untuk mengisi ARGn.

Warna pada pencahayaan specular diisi ke ARGn.

 

 

Listing 2 berisi contoh bagaimana mengatur ARG1 dan ARG2 pada stage 1. ARG1 diisi dengan warna texel dan ARG2 diisi dengan warna diffuse terinterpolasi.

D3DTSS_COLOROP, D3DTSS_ALPHAOP

D3DTSS_COLOROP dan D3DTSS_ALPHAOP masing-masing digunakan untuk mengatur stage agar menggunakan operasi pencampuran warna dan alpha. Operasi yang bisa dikerjakan ditentukan oleh tipe enumerasi D3DTEXTUREOP seprti pada Tabel 2.

 

TABEL 2. OPERASI PADA TEKSTUR STAGE

OPERASI

D3DTOP_DISABLE 

D3DTOP_SELECTARG1 

D3DTOP_SELECTARG2 

D3DTOP_MODULATE 

D3DTOP_MODULATE2X 

D3DTOP_MODULATE4X 

D3DTOP_ADD 

D3DTOP_ADDSIGNED 

D3DTOP_ADDSIGNED2X 

D3DTOP_SUBTRACT 

D3DTOP_MULTIPLYADD 

D3DTOP_LERP 

KETERANGAN

Operasi pada stage ini dimatikan.

Output stage sama dengan ARG1. Argumen lain diabaikan.

Output stage sama dengan ARG2. Argumen lain diabaikan.

Output stage = ARG1 * ARG2. Karena melipatkan perkalian

fl oating-point, outputnya lebih gelap dari inputnya. Contoh

0.6, 0.6, 0.6) * (0.5, 0.5, 0.5) = (0.3, 0.3, 0.3).

Output stage = (ARG1 * ARG2) * 2. Outputnya lebih terang.

Jika melebihi 1.0, nilainya dibatasi 1.0 (putih terang).

Output stage = (ARG1 * ARG2) * 4. Outputnya jauh lebih

erang. Jika melebihi 1.0, nilainya dibatasi 1.0.

Output stage = ARG1 + ARG2.

Output stage = ARG1 + ARG2 - 0.5. Nilainya menjadi

berkisar -0.5 hingga 0.5.

Output stage = (ARG1 + ARG2 – 0.5) * 2

Output stage = ARG1 – ARG2

Output stage = ARG1 + (ARG2 * ARG0)

Output stage = ARG1 * ARG2 + (1-ARG1) * ARG0. Interpolasi

inier.

 

 

Listing 2 berisi contoh bagaimana melakukan multi-texturing dengan dua texture stage.

Anda perlu mengubah deklarasi tipe TTerrainVertex dengan menyertakan dua koordinat tekstur pada tiap vertex agar tiap tekstur dapat diatur koordinatnya secara independen. Deklarasi flexible vertex format (FVF) perlu diubah dari D3DFVF_TEX1 menjadi D3DFVF_TEX2 (Listing 3).

Pencampuran Tekstur Berdasarkan Ketinggian

Untuk membuat terrain semakin menarik, kita akan menghasilkan tekstur yang bervariasi hasil pencampuran beberapa tekstur berdasarkan ketinggian vertex-vertex penyusun terrain. Pada bagian terrain yang ketinggiannya rendah, terrain digambar dengan tekstur rumput (Tekstur 0), daerah yang lebih tinggi digambar dengan tekstur lumpur (Tekstur 1), Daerah tertinggi digambar dengan tekstur bebatuan (Tekstur 2) (Gambar 9).

Daerah yang ketinggiannya terletak antara daerah rumput   dan daerah lumpur (0.0-0.5), diinterpolasi sehingga menghasilkan transisi halus dari daerah rerumputan ke daerah berlumpur. Pada ketinggian 0.0, opacity Tekstur 0 dan Tekstur 1 masing-masing adalah 1.0 (100%) dan 0.0 (0%). Pada ketinggian 0.5, opacity Tekstur 0 dan Tekstur 1 masing-masing adalah 0.0 (0%) dan 1.0 (100%). Cara serupa dikerjakan untuk daerah yang ketinggiannya antara 0.5-1.0.

Implementasi lengkap teknik ini dapat Anda temukan di demo 7c pada CD/DVD.

 

Listing 1

FDevice.SetSamplerState(0,

                        D3DSAMP_ADDRESSU,

                        D3DTADDRESS_WRAP);

FDevice.SetSamplerState(0,

                        D3DSAMP_ADDRESSV,

                        D3DTADDRESS_WRAP);

Listing 1

//pass 1 texture #1

FDevice.SetTextureStageState(0,

                    D3DTSS_COLORARG1,

                    D3DTA_TEXTURE );

FDevice.SetTextureStageState(0,

                    D3DTSS_COLOROP,

                    D3DTOP_SELECTARG1);

FDevice.SetRenderState(D3DRS_ALPHABLENDENABLE,

                    FALSE);

FDevice.SetTexture(0,FTexture1);

//lakukan penggambaran poligon

do_draw_primitives();

//pass 2 texture #2

FDevice.SetRenderState(D3DRS_ALPHABLENDENABLE,

                     TRUE);

FDevice.SetRenderState(D3DRS_SRCBLEND,

                 D3DBLEND_ONE);

FDevice.SetRenderState(D3DRS_DESTBLEND,

                 D3DBLEND_ONE);

FDevice.SetTexture(0,FTexture2);

//lakukan penggambaran poligon

do_draw_primitives();

Listing 2

//gunakan tekstur 0 dan kombinasi dengan warna diffuse

FDevice.SetTexture(0,FTexture);

Fdevice.SetTextureStageState(0,

                   D3DTSS_COLORARG1,

                   D3DTA_TEXTURE);

Fdevice.SetTextureStageState(0,

                   D3DTSS_COLORARG2,

                   D3DTA_DIFFUSE);

Fdevice.SetTextureStageState(0,

                   D3DTSS_COLOROP,

                   D3DTOP_MODULATE);

//gunakan hasil kombinasi tekstur 0 dan warna diffuse

//kombinasi dengan detail tekstur

FDevice.SetTexture(1,FDetailTexture);

FDevice.SetTextureStageState(1,

                   D3DTSS_COLORARG1,

                   D3DTA_CURRENT);

FDevice.SetTextureStageState(1,

                   D3DTSS_COLORARG2,

                   D3DTA_TEXTURE);

FDevice.SetTextureStageState(1,

                   D3DTSS_COLOROP,

                   D3DTOP_ADDSIGNED);

Listing 3

const D3DFVF_TERRAIN=D3DFVF_XYZ or D3DFVF_NORMAL or D3DFVF

TEX2;

type

  TTerrainVertex=packed record

    position:TD3DVector;

    normal:TD3DVector;

    u,v:single;

    u2,v2:single;

  end;

 

 

LEBIH LANJUT

·         Wolfgang F. Engel, “Beginning Direct3D Game Programming”, Second Edition, Premier Press, 2003.

·         Gary Simmons, Adam Hoult, “Graphics Programming with DirectX 9 : Part I”, e-Institute Publishing, Inc, 2004.

·         Microsoft, “DirectX 9.0 SDK Documentation”, Microsoft Corporation, 1995-2003.

 
PC Media
Be Powerful with Vista
No.08/2008

Tidak ada polling
all right reserved, copying or reproducing any material on this website
without prior consent from PC Media is Prohibited