Advanced Effect 2
Level 14 GRAFIKA KOMPUTER DAN ANIMASI
2
Getting Started with HLSL What is HLSL?
The Programmable Pipeline Loading Shaders in DirectX
The Finished Program The Vertex Shader
Vertex Shader
The Finished Program
3
Simple Vertex Lighting
Math
Normals and Lights
Implementing Light
The Finished Program
Loading Lights from DirectX
Adding Lights in DirectX
The Finished Program
Some Simple Vertex Effects
Specular Light Shader
Vertex Fog Shader
The Finished Program
4
Pada pembahasan minggu lalu, kita hanya
memperoleh siluet putih dari sebuah
teapot
.
Sebenarnya, kita baru melakukan pengaturan
paling dasar dari
vertex transformations
.
Kita hanya mengonversi titik-titik 3D menjadi
2D dan menggambarnya pada layar sebagai
warna putih.
Sekarang, kita akan membahas tentang
pencahayaan.
5
Ada 2 hal penting yang perlu Anda ketahui, yakni
cosine dan dot product.
1. Cosine (atau cos)
Merupakan suatu fungsi trigonometri yang digunakan dalam bangun segitiga dan lingkaran.
6
Merupakan hasil kali besaran 2 vektor dengan cosine
sudut di antara 2 vektor tersebut.
S E N G -H A N S U N
7
Di awal, kita pernah membahas tentang teknik
pencahayaan dan bagaimana normals dapat digunakan untuk membantu menghitung berapa banyak cahaya yang jatuh di suatu obyek.
Sekarang, kita akan membahas lebih detail, sehingga kita dapat membuat cahaya di HLSL.
Inti persoalan dalam menghitung vertex lighting
adalah menemukan sudut cahaya dan normal, dan menentukan dot product-nya.
Nilai dari dot product kemudian dikalikan dengan
warna dari cahaya, untuk menghasilkan warna cahaya terakhir.
8
Ingat bahwa suatu dot product adalah nilai cosine dari
sudut antara 2 vektor, yang selalu menghasilkan nilai
antara 1 dan -1 (nilai negatif dihasilkan oleh sudut antara 900 dan 2700).
Jika cahaya jatuh tepat di atas suatu titik, sudut normal
dan cahaya akan tepat 00 dan kita peroleh dot product
bernilai 1.
Jika cahaya yang datang dan normal membentuk sudut
900, diperoleh dot product bernilai 0.
Jika cahaya datang langsung dari belakang (sudut 1800),
maka dot product bernilai -1, dan demikian seterusnya.
Tidak peduli berapa besar sudutnya, dot product selalu
mengembalikan jumlah cahaya yang jatuh di sebuah titik.
9
Setelah didapatkan dot product dari kedua vektor ini, yang harus dilakukan adalah memastikan bahwa
nilainya 0 atau lebih, dan menggunakannya untuk mengubah warna asli vertex tersebut.
Contoh:
10
Untuk menyederhanakan, kita akan membuat cahaya di
dalam shader, bukan di DirectX.
Code-nya mirip seperti project pertama minggu lalu, yang diubah hanya fungsi Vshader().
Langkah-langkah yang perlu dilakukan:
1. Add a parameter for the vertex normal
2. Create values to hold the properties of the light
3. Create and calculate two vectors for the light and for
the vertex normal
4. Calculate the dot product and multiply it by the diffuse
color
5. Complete the vertex transformation
11
Jika Anda perhatikan fungsi Vshader() pada minggu sebelumnya, Anda akan melihat bahwa hanya ada 1 parameter fungsi, yakni posisi dari titiknya.
Tentunya pencahayaan memerlukan suatu normal
juga, yang tidak dapat kita hitung di sini.
Untuk menghitungnya, perlu diketahui lokasi dari setiap titik yang saling berkaitan.
Karena vertex shader hanya menangani 1 titik pada satu waktu, maka hal ini tidak mungkin dilakukan. Oleh karenanya, normal ditangani oleh mesh, dan
DirectX akan meneruskan vertex normal dan posisinya.
12
Jadi parameter yang baru disebut Normal, dan terlihat seperti berikut.
float3 Normal : NORMAL.
13
Pada langkah ini, kita akan membuat nilai-nilai yang menyimpan semua informasi yang dibutuhkan untuk menghitung cahaya, seperti warna cahaya, baik diffuse
dan ambient, maupun posisi cahaya.
Cahaya yang akan dibuat merupakan kombinasi antara spot light dan directional light.
Cahaya ini akan memancar dari suatu lokasi
tertentu, namun tidak akan pernah pudar saat makin jauh.
Ini kelebihan dari HLSL, kita dapat mem-bypass
sistem apapun dalam DirectX dan menjalankan apa yang kita inginkan.
14
3 nilai yang akan kita buat adalah LightPos, DiffuseColor, dan AmbientColor.
Jadi selain membuat VertexOut, kita buat 3 nilai:
Perhatikan bahwa nilai-nilai ini memiliki tipe float3, yakni sebuah larik dengan 3 floats.
Cahaya diposisikan pada 2x2x2.
2 warna yang kita miliki diatur menjadi .5x.5x.5
15
Multiply the vertex’s position by the World
matrix multiplying normal with world matrix Calculate the normal vector by
Creates a new float3 called LightVec and stores the light vector in it. To do this, we must call the normalize() intrinsic that results in a precise vector
16
Calculate the dot product using dot() intrinsic. This has 2 parameters, which are the 2 vectors we wish to find the dot product of. Then, we
have to multiply the returned value by the diffuse color
Find the final color by adding the modified diffuse color to the ambient color
Find out whether the DiffuseColor has dropped below 0 or not. We use max() intrinsic, so that it returns DiffuseColor if it
17
Sebelumnya, kita telah mengalikan vertex dengan
world matrix.
Sisanya tinggal mengalikan view dan projection matrices.
18 S
19 S
20 S
21 S
22 S
23 S
24 S
25 S
26 S
27 S
28 S
29 S
30 S
31
Kita telah berhasil membuat cahaya sederhana yang disisipkan dalam suatu shader.
Cara tersebut cukup mudah, namun sayangnya kita hanya dapat membuat cahaya yang tidak berubah dengan cara ini.
Cara paling baik untuk mengatur cahaya adalah dengan cara yang umum digunakan yakni dengan
code DirectX, D3DLIGHT9 struct.
Sekarang kita akan mempelajari cara membuat cahaya dengan D3DLIGHT9 dan meneruskan nilainya ke dalam HLSL.
32
Dalam DirectX, kita menggunakan D3DLIGHT9 untuk
membuat dan memanipulasi cahaya.
Dalam HLSL, kita dapat memanfaatkan cahaya ini, namun
hanya sejauh menyimpan informasi cahaya.
Terdapat beberapa fungsi cahaya yang tidak didukung
oleh HLSL.
Kita tidak perlu lagi mengatur apa jenis cahaya yang
digunakan, atau mengaktifkan – nonaktifkan cahaya
secara manual.
HLSL menganggap semua cahaya dinyalakan, dan
menangani cahaya berdasarkan algoritma yang digunakan, bukan berdasarkan jenis cahaya yang Anda atur.
33
Dalam effect file, hanya ada sedikit perubahan.
Kita harus memindahkan 3 baris code ke atas, dan
mengubah nama sebuah variabel.
Jika Anda perhatikan, kita hanya memindahkan float3 ke
atas (sama seperti float4x4) dan menghilangkan inisialisasinya.
Juga di dalam shader code, kita ganti DiffuseColor menjadi
NewDiffuseColor.
Hal ini karena globals dianggap sebagai konstanta.
Oleh karena itu, kita buat sebuah float3 baru yang
disebut NewDiffuseColor, dan menggunakannya untuk menjalankan perhitungan.
34
Dalam source file, kita harus membuat sebuah fungsi yang menghasilkan sebuah cahaya.
35
Perhatikan bahwa fungsi ini jauh lebih kecil dibandingkan saat materi sebelumnya.
Kita telah menghilangkan elemen-elemen tidak penting yang tidak akan digunakan oleh HLSL. Setelah membuat cahaya, kita harus mengatur
nilainya di dalam HLSL shader.
Caranya sama seperti saat kita mengatur matriks.
Namun, dibanding menggunakan SetMatrix(), kita akan menggunakan fungsi SetFloatArray().
36
Fungsi ini bekerja dengan cara yang serupa seperti SetMatrix(), kecuali bahwa fungsi ini dapat digunakan untuk mengisi suatu float, float2, float3, float4, dan seterusnya.
Namun, diperlukan suatu parameter tambahan.
S
The name of the value we are passing to
The number of float values which need to be passed
37 S
38 S
39 S
40 S
41 S
42 S
43 S
44 S
45 S
46 S
47 S
48 S
49 S
50 S
51 S
52
Sekarang kita akan mempelajari 2 trik baru yang dapat dilakukan dengan shaders.
Yang pertama adalah specular light. Pada dasarnya, ini adalah cara membuat permukaan terlihat mengilap. Yang kedua adalah efek kabut. Banyak games yang
tidak dapat me-render obyek yang berada jauh di belakang. Untuk menanganinya, para programmer
membuat kabut di dunia game untuk
menyembunyikan obyek-obyek yang terlalu jauh
53
Kita sudah pernah membahas specular light pada pertemuan minggu ke-5.
Sekarang kita akan menyisipkan suatu specular reflection dalam shader kita.
Sebelumnya, kita perlu mengetahui formula berikut.
Formula di atas dapat juga ditulis sebagai.
54
Shine
Merupakan suatu konstanta float yang merepresen-tasikan seberapa reflective permukaan obyek kita nantinya. Semakin tinggi nilainya, semakin kurang
reflective, dan sebaliknya. EyeVec
Merupakan variabel baru yang mirip seperti
LightVec, kecuali EyeVec merupakan arah antara kamera dan titiknya. Kita harus meneruskan posisi kamera dari aplikasi DirectX. Kita dapat
menggunakan nilai ini dan posisi titik untuk menghitung camera vector.
55 S
56 S
57 S
58 S
59 S
60 S
61 S
62 S
63 S
64 S
65 S
66 S
67 S
68 S
69
Banyak game menggunakan efek kabut untuk membuat sebuah dunia yang luas dengan low rendering power.
Tujuan kabut ini adalah untuk menyembunyikan
kenyataan bahwa obyek-obyek yang jauh tidak akan digambarkan.
Ada beberapa cara untuk mengatur hal ini dengan menggunakan fixed-function pipeline, namun sekarang kita mempelajari programmable pipeline.
Jadi kita akan menyisipkan efek kabut ini ke dalam
70
Untungnya, menciptakan efek kabut tidak
memerlukan terlalu banyak persamaan Matematika. Teori yang perlu diketahui hanyalah konsep bahwa
jarak suatu obyek dari kamera menentukan
perubahan dari warna aslinya menjadi warna kabut itu sendiri.
Kita juga harus tahu cara mendapatkan jarak itu, yakni dengan Vert.Pos.z.
71
Langkah-langkah penerapan efek kabut:
1. Find the difference between the fog color and the
vertex color
2. Multiply the difference by the vertex distance
divided by the fog limit
3. Add the fog color to the final color
4. Ensure the final color is not brighter than the fog
itself
72
Banyak yang berasumsi bahwa kabut berwarna putih,
namun sebenarnya warna kabut abu keputihan dengan sedikit bayangan biru.
Untuk menemukan selisih antara warna vertex dan warna
kabut, harus ditentukan warna kabut terlebih dahulu.
Untuk sekarang, digunakan warna 230, 230, 255 (.9, .9, 1),
yakni warna abu-abu dengan sedikit biru.
Untuk menemukan selisihnya, kita gunakan code berikut.
73
Sebenarnya, kita dapat hanya mengalikan selisih yang diperoleh dengan vertex distance, namun kita tidak akan dapat melihat hasilnya lebih dari 1 unit.
Hal ini akan cukup mengganggu.
Jadi kita tambahkan pembagian dengan fog limit, yang secara signifikan mengurangi perubahan warna,
membuat obyek-obyek memudar dengan lebih baik.
74
Yang ini juga mudah.
Setelah memperoleh warna, kita hanya perlu
menambahkan warna yang diperoleh ke vertex color.
75
Titik-titik yang melewati fog limit cendrung di-render
dengan warna yang lebih terang dibandingkan warna kabut itu sendiri.
Untuk menghindarinya, kita cukup bandingkan
FinalColor dengan FogColor, dan mengambil nilai yang terkecilnya.
76 S
77 S
78 S
79 S
80 S
81 S
82 S
83 S
84 S
85 S
86 S
87 S
88 S
89 S
90
http://directxtutorial.com/
http://en.wikipedia.org/wiki/Dot_product Other web resources.