Khóa luận Nghiên cứu và xây dựng thử nghiệm 3D Engine - Phần 5

Điều kiện tiên quyết của thuật toán đổbóng là ta phải tính được hình khối của

shadow volume mà nội dung chính là ta phải tìm được các cạnh bao. Một cạnh (bất

kỳ) được cấu tạo bởi hai điểm và có từ1 đến 2 mặt kềliền với nó, cạnh đó được gọi

là cạnh bao khi nó chỉcó 1 mặt kềhay có 2 mặt kềnhưng một mặt hướng vềphía

ánh sáng trong khi mặt còn lại thì không.

pdf17 trang | Chuyên mục: Mạng Máy Tính | Chia sẻ: dkS00TYs | Lượt xem: 1730 | Lượt tải: 1download
Tóm tắt nội dung Khóa luận Nghiên cứu và xây dựng thử nghiệm 3D Engine - Phần 5, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
trời. 
4.3.1. Cơ sở lý thuyết 
¾ Cách biểu diễn bầu trời bằng hình khối và texture. 
 Vì bầu trời là khung cảnh đóng nên các hình khối đóng được sử dụng khá nhiều 
để thể hiện bầu trời. Các hình khối thường được sử dụng là hình khối vuông (box), 
hình cầu hay bán cầu (sphere). Các texture được sử để tạo khung cảnh bầu trời 
thường là các texture biểu hiện 6 mặt của không gian xung quanh (dùng cho box) 
hay các texture liền nhau ở các cạnh (dùng cho sphere). 
 Chương 4. Các thuật toán Vertex và Pixel Shader 
 - 65 - 
Hình 4-9 Texture liền nhau ở các cạnh dùng cho sky sphere 
Hình 4-10 Texture 6 mặt dùng cho sky box 
¾ Các đặc tính của bầu trời trong thực tế 
 Khung cảnh bầu trời trong thực tế có các đặc tính đây mà ta cần quan tâm khi 
muốn thiết kế Vertex Shader. 
 Rất xa so với tầm nhìn, khi ta nhìn tập trung vào 1 huớng thì dù ta có di 
chuyển đến đâu di nữa thì theo hướng nhìn (với điều kiện khoảng cách không quá 
lớn) thì hình ảnh mà ta nhận được từ bầu trời là không đổi. 
 Tuy nhiên hình ảnh từ bầu trời mà ta nhận được sẽ thay đổi khi ta nhìn ở các 
hướng khác nhau. 
 Từ các đặc tính trên của bầu trời ta xác định được cách thức biểu diễn bầu trời 
trong 3D như sau: 
 Sử dụng một hình khối để làm vật chứa và sử dụng 1 texture có hình khung 
cảnh bầu trời. 
 Chương 4. Các thuật toán Vertex và Pixel Shader 
 - 66 - 
 Vì ta không thể nào đi xuyên qua bầu trời, nên ta phải luôn cập nhật vị trí của 
hình khối bầu trời = vị trí hiện thời của camera (hay vị trí của mắt) (thỏa mãn tính 
chất 1). 
 Chỉ cập nhật vị trí mà không thay đổi góc xoay của hình khối bầu trời nhằm 
khiến cho hình khối bầu trời không thay đổi theo hướng xoay của camera (thỏa mãn 
tính chất 2). 
 Sau đây là hình vẽ minh họa cho ý tưởng. 
Hình 4-11 Tọa độ của skybox được cập nhật theo tọa độ camera 
4.3.2. Vertex Shader cho skybox 
 Vertex Shader cho skybox khá đơn giản như sau: 
struct VS_INPUT { 
 float4 position : POSITION; 
 float2 texcoord : TEXCOORD0; 
}; 
struct VS_OUTPUT { 
 float4 position : POSITION; 
 float4 color : COLOR0; 
 float2 texcoord : TEXCOORD0; 
}; 
VS_OUTPUT main( VS_INPUT i ) 
 Chương 4. Các thuật toán Vertex và Pixel Shader 
 - 67 - 
{ 
 VS_OUTPUT o; 
 // Skybox local transform 
 float3 worldPos = mul( float4( i.position.xyz, 0 ), cModel[0] ); 
 // Vertex world position = eye position 
 worldPos += cEyePos; 
 // Transform vertex to projection space 
 float4 projPos = mul( float4( worldPos, 1 ), cViewProj ); 
// Sky is far away, so depth value = 1.0f 
 projPos.z = 0.9999f * projPos.w; 
o.position = projPos; 
 // Final color 
 o.color = 1.0f; 
 o.texcoord = i.texcoord; 
 return o; 
} 
 Trước tiên ta phải biến đổi sky box bằng ma trận thế giới, việc này có vẻ như là 
không cần thiết vì ta sẽ sử dụng vị trí của mắt (hay camera) làm vị trí cho skybox. 
Nhưng thực tế công việc này cho phép ta triển khai 1 số thuộc tính ban đầu cho 
skybox như độ cao đối với tầm mắt, độ phóng đại… 
 Sau khi cộng thêm tọa độ của mắt vào, ta phải biến đổi vertex vào không gian 
chiếu bằng cách nhân với ma trận View * Projection. 
 Vì skybox ở rất xa nên ta cho độ sâu = 1.0f (để các điểm ảnh của skybox không 
thể vượt qua giá trị độ sâu của các điểm ảnh khác khi kiểm tra độ sâu (depth test)) 
công đoạn này phải nhân với projPos.w vì để chuẩn bị cho giai đoạn chuẩn hóa hệ 
tọa độ thuần nhất sau khi kết thúc Vertex Shader. 
4.3.3. Một số kết quả đạt được 
 Khung cảnh bầu trời được vẽ ra đảm bảo đúng các đặc tính của bầu trời trong 
thực tế, cho dù ta có di chuyển camera thế nào đi nữa, ta cũng không thể “đi xuyên” 
qua bầu trời được. Các cảnh sau đây được chụp từ Game demo. 
 Chương 4. Các thuật toán Vertex và Pixel Shader 
 - 68 - 
Hình 4-12 Khung cảnh bầu trời chính diện 
Hình 4-13 Một góc nhìn khác của bầu trời 
 Chương 4. Các thuật toán Vertex và Pixel Shader 
 - 69 - 
4.4. Chiếu sáng theo điểm ảnh (per-pixel lighting) sử dụng normal 
map và specular map 
 Hiện nay hiệu ứng chiếu sáng trên từng điểm ảnh được sử dụng khá phổ biến 
trong các Game nhằm tăng cường chất lượng đồ họa cho Game. Thay vì chiếu sáng 
theo từng đỉnh vertex, per-pixel lighting cho chất lượng đồ họa cao hơn hẳn do có 
thể áp dụng nhiều thuật toán mới trong đồ họa 3 chiều như bump bề mặt bằng 
normal map, phản chiếu bề mặt bằng specular map… 
 Ứng dụng khi tự thực hiện chiếu sáng trên điểm ảnh bằng Shaders phải giải 
quyết các tất cả các vấn đề về chiếu sáng như diffuse lighting, specular lighting… 
 Diffuse lighting trong Engine chủ yếu sử dụng bump bằng normal map và 
specular lighting chủ yếu sử dụng specular map, 2 thuật toán chiếu sáng này sẽ 
được trình bày kỹ ở phần này. 
4.4.1. Cơ sở lý thuyết 
 Ở phần này sẽ đề cập chi tiết vào qui trình chiếu sáng trên điểm ảnh được 
Engine hỗ trợ. Qui trình chiếu sáng trên điểm ảnh chủ yếu phân ra làm 2 công đoạn 
riêng biệt: thực hiện tính toán màu chính (diffuse color) và tính toán màu phản 
chiếu (specular color). 
¾ Tính toán màu diffuse (có bump bề mặt bằng normal map) 
 Trước khi đi chi tiết vào thuật toán ta cần xem qua 1 số khái niệm mới dùng 
trong phần này 
 Không gian tiếp tuyến của vật thể (tangent space). 
 Tọa độ texture tại mỗi đỉnh (vertex) hình thành một hệ trục tọa độ 3 chiều với 
trục U (tiếp tuyến), trục W (pháp tuyến) và trục V (binormal = U x W). Hệ trục tọa 
độ này gọi là không gian tiếp tuyến hay không gian texture của vật thể tại các đỉnh 
(vertex). 
 Chương 4. Các thuật toán Vertex và Pixel Shader 
 - 70 - 
Hình 4-14 Không gian tiếp tuyến 
 Normal map là gì? 
 Normal map là một texture nhưng có đặc tính khá đặc biệt, thay vì chứa thông 
tin về điểm màu như texture thông thường, normal map lai chứa thông tin về không 
gian tiếp tuyến (tangent space) hay không gian texture (texture space) của vật thể, 
hay nói cách khác nếu các điểm ảnh của texture biểu diễn màu sắc của vật thể tại 1 
điểm thì normal map sẽ biểu diễn không gian tiếp tuyến của vật thể tại điểm đó. 
 Mỗi điểm ảnh của normal map có định dạng là RGBA trong đó 3 thành phần 
RGB có giá trị [0..1] được ánh xạ từ 3 trục U, V, W có giá trị trong khoảng [-1, 1]. 
 Normal map có thể tạo ra bằng 2 cách, dùng height map (texture dạng graycale 
chứa thông tin độ sâu về bề mặt của vật thể trong đó màu sáng hơn biểu thị độ cao 
lớn hơn). Cách thứ 2 phức tạp hơn do phải tạo thêm 1 vật thể khác có độ chi tiết cao 
hơn, sau đó ta so sánh sự khác nhau giữa 2 vật thể để tạo ra normal map (quá trình 
này có thể được thực hiện bằng tool Melody của NVidia). 
Hình 4-15 Tạo normal map từ height map 
 Chương 4. Các thuật toán Vertex và Pixel Shader 
 - 71 - 
Hình 4-16 Tạo normal map từ vật thể có độ chi tiết cao hơn bằng Melody (NVidia) 
 Bump bề mặt sử dụng normal map 
 Bump bề mặt chủ yếu được thực hiện trên Pixel Shader cho từng điểm ảnh. 
Thuật toán này sử dụng giá trị normal trong normal map để xác định mức độ của 
ánh sáng tác động vào điểm ảnh đó bằng cách nhân tích vô hướng giá trị normal 
trên với vector hướng ánh sáng trong không gian tiếp tuyến. Sau đó giá trị này được 
nhân với màu sắc của vertex và màu lấy mẫu từ texture để tính ra màu diffuse (màu 
của vertex được tính trong Vertex Shader) 
light factor = dot product (normal, light vector ) 
diffuse color = light factor * vertex color * texture color; 
 Trong đó 
 normal. Vector pháp tuyến (normal vector) tại điểm đó, normal vector có 
được do lấy mẫu từ normal map. 
 light vector. Vector hướng ánh sáng trong không gian tiếp tuyến (tangent 
space), vector này được tính trong Vertex Shader và được truyền vào Pixel Shader 
để sử dụng. 
 vertex color. Màu của vertex sau khi thực hiện chiếu sáng trên vertex (per-
vertex lighting) trong Vertex Shader. 
 texture color. Màu của texture chính, có được do lấy mẫu texture. 
 Chương 4. Các thuật toán Vertex và Pixel Shader 
 - 72 - 
Hình 4-17 Chiếu sáng theo từng vertex trong Vertex Shader 
 Hình 1. Dữ liệu vertex trong bộ nhớ (được vẽ dưới dạng wireframe) 
 Hình 2. Chiếu sáng trên từng đỉnh (per-vertex lighting) bằng Vertex Shader 
Hình 4-18 Chiếu sáng trên từng điểm ảnh trong Pixel Shader 
 Hình 1. Chiếu sáng trên từng pixel (sử dụng tích vô hướng giữa normal và 
vector hướng ánh sáng). 
 Hình 2. Sau khi kết hợp với lấy mẫu từ texture chính. 
¾ Tính toán màu specular (sử dụng specular map) 
 Specular map là gì ? 
 Specular map là texture dạng grayscale, specular map có tác dụng cho biết vùng 
nào của vật thể phản chiếu nhiều ánh sáng vùng nào phản chiếu ít ánh sáng (tương 
ứng với màu trong specular map từ sáng tới tối). 
 Tính độ phản chiếu của ánh sánh 
 Độ phản chiếu (phản xạ) của ánh sáng trên vật thể thì phụ thuộc vị trí của mắt 
(hay camera). Khi mắt nằm ngay trên đường phản xạ của ánh sáng thì mắt sẽ nhìn 
 Chương 4. Các thuật toán Vertex và Pixel Shader 
 - 73 - 
thấy một vùng ánh sáng chói do toàn bộ năng lượng của ánh sáng được truyền thẳng 
vào mắt. 
Hình 4-19 Sự phản xạ của tia sáng trên bề mặt 
 Muốn tính màu specular của điểm ảnh ta phải xác định được mức độ ánh sáng 
phản chiếu tại điểm đó. Công thức tính vector phản chiếu (phản xạ) như sau: 
R = 2(L dot N)N - L 
 Trong đó: 
 L. Light vector 
 R. Reflection vector 
 N. Normal 
 Mức độ phản chiếu của ánh sáng phụ thuộc rất nhiều vào chất liệu bề mặt của 
vật thể, các bề mặt nhẵn bóng có độ phản chiếu lớn trong khi các bề mặt gồ ghề lại 
có độ phản chiếu thấp. Để tránh công việc phải phân rã vật thể ra thành nhiều thành 
phần để dựng hình với các mức phản chiếu khác nhau người ta dùng specular map 
như một lookup table để xác định mức độ phản chiếu của ánh sánh trên từng điểm 
ảnh. 
reflection vector = 2 * dotproduct (normal, light vector) * normal - light vector 
specular factor = dotproduct (reflection vector, view vector) 
specular color = (specular factor ^ specular constant) * specular lookup 
 Trong đó 
 normal. Vector pháp tuyến (normal vector) tại điểm đó, normal vector có 
được do lấy mẫu từ normal map. 

File đính kèm:

  • pdfthu_nghiem_3d_engine_5.pdf