Khóa luận Nghiên cứu và xây dựng thử nghiệm 3D Engine - Phần 2
Trong công nghệGame tiên tiến ngày nay hầu hết các Game được xây dựng dựa
trên một Game Engine. Việc xây dựng nên các Game Engine đã trởthành một xu
thếtất yếu và phát triển rất mạnh mẽ. Mỗi Game Engine đều chứa đựng trong nó
nhiều thành phần, tập các thành phần xửlý hiển thị3D của Game Engine chính là
3D Engine. Chất lượng của Game Engine phụthuộc vào chất lượng của 3D Engine,
có thểnói 3D Engine chính là phần đặc trưng cơbản nhất của Game Engine.
Chúng ta có thểchia các Game Engine ra thành 3 loại là Isometric Engine, FPS
Engine và MMOG Engine. Tuy nhiên việc phân chia các Engine chỉmang tính
tương đối vì ngày này các Engine mang trong mình rất nhiều chức năng pha trộn từ
các loại khác nhằm đáp ứng việc xây dựng Game tốt nhất.
như HLSL (chỉ có trong Direct3D 9.0 trở lên) hay GLSL (được phát triển trong phiên bản OpenGL 2.0). Phần này sẽ đề cập tới cấu trúc 1 chương trình Vertex Shader viết bằng hợp ngữ, các ngôn ngữ cấp cao sẽ được trình bày ở cuối chương này. Một chương trình Vertex Shader viết bằng hợp ngữ căn bản được chia thành các phần sau đây: Chương 2. Vertex Shader và Pixel Shader - 16 - Hình 2-4 Cấu trúc 1 chương trình Vertex Shader bằng hợp ngữ Chỉ thị phiên bản (Version Instruction). Là thành phần đầu tiên trong chương trình, nó cho biết phiên bản Vertex Shader được biên dịch thành. Trong ví dụ trên chương trình sẽ chạy được trên phần cứng hỗ trợ vs_1_1 trở lên. Ghi chú (Comments). Được dùng để ghi các ghi chú trong chương trình như ý nghĩa của dữ liệu chứa trong thanh ghi… Ghi chú được bắt đầu bằng ( // ) hay ( ; ) cho ghi chú 1 dòng và ( /* … */ ) cho ghi chú nhiều dòng. Các hằng thanh ghi (Constants). Các hằng được định nghĩa sau từ khoá def. Các hằng thanh ghi có thể chứa tới 4 giá trị cho mỗi thanh ghi. Như ở ví dụ trên thanh ghi c8 được gán giá trị là (0, 1, 2, 3). Các hằng thanh ghi còn có thể được gán giá trị bên trong chương trình chính thông qua phương thức IDirect3DDevice9::SetVertexShaderConstantx. Định nghĩa dữ liệu trong thanh ghi đầu vào (Input Register Declarations). Các thanh ghi dữ liệu vào như v0, v1… cần phải được định nghĩa dữ liệu trước khi sử dụng. Việc định nghĩa này sẽ giúp Direct3D ánh xạ được các dữ liệu thành phần trong vertex trên bộ nhớ vào đúng các thanh ghi tương ứng. Trong ví dụ trên, thanh ghi v0 sẽ chứa tọa độ vị trí, và v1 sẽ chứa tọa độ texture của vertex. Chương 2. Vertex Shader và Pixel Shader - 17 - Các vi lệnh (Instructions). Phần cuối cùng của 1 chương trình Vertex Shader là các vi lệnh hợp ngữ. Mọi chương trình Vertex Shader đều phải xuất giá trị ra ít nhất là vào thanh ghi vị trí oPos. Trong ví dụ trên chương trình xuất vào 2 thanh ghi là thanh ghi vị trí oPos và thanh ghi tọa độ texture oT0. 2.4. Pixel Shader Pixel Shader là chương trình tính toán và xử lý màu trên 1 hay nhiều điểm ảnh. Pixel Shader sẽ được thực thi 1 lần cho mỗi điểm ảnh được dựng lên màn hình từ dữ liệu vertex vì thế Pixel Shader khi chạy sẽ tốn nhiều thời gian hơn Vertex Shader (chỉ xử lý 1 lần cho mỗi vertex). Pixel Shader có thể được viết bằng hợp ngữ hay HLSL. Các phiên bản hiện nay của Pixel Shader gồm có ps_1_1, ps_1_2, ps_1_3, ps_1_4, ps_2_0, ps_2_x và cuối cùng là ps_3_0. Cũng giống như Vertex Shader, Pixel Shader khi thi hành sẽ loại trừ với Fixed Function, do đó tìm hiểu qui trình xử lý pixel của Fixed Function là điều cần thiết. 2.4.1. Xử lý điểm ảnh bằng Fixed Function Pipeline Sau khi dữ liệu vertex được xử lý (thành tọa độ trong không gian chiếu) sẽ được chuyển qua để xử lý đối tượng cơ sở (Primitive Processing). Hình 2-5 Qui trình xử lý đối tượng cơ sở Clipping. Loại bỏ các các đối tượng hình học không nhìn thấy được trong khối quan sát (viewing frustum) để tăng hiệu suất dựng hình. Chương 2. Vertex Shader và Pixel Shader - 18 - Chuẩn hóa hệ tọa độ thuần nhất (Homogeneous Divide). Chia các thành phần của dữ liệu cho phần tử cuối. Ánh xạ Viewport (Viewport Scaling). Ánh xạ dữ liệu vào tọa độ trong Viewport. Xử lý tam giác (Triangle Setup). Chuẩn bị cho việc nội suy tam giác và biến đổi các thuộc tính vertex thành thuộc tính điểm ảnh. Sau khi qui trình xử lý đối tượng cơ sở hoàn tất, dữ liệu vertex đã được nội suy thành dữ liệu điểm ảnh sẵn sàng được chuyển sang qui trình xử lý điểm ảnh (điểm ảnh lúc này chưa phải là giá trị màu mà chỉ mang các thuộc tính do tính toán được từ việc nội suy tam giác mà thôi). Điểm ảnh sau đó sẽ tính toán kết hợp các thuộc tính màu sắc và lấy mẫu texture tạo thành điểm màu cuối cùng. Qui trình xử lý điểm ảnh bao gồm 2 công đoạn chính. Hình 2-6 Qui trình xử lý điểm ảnh qua 2 giai đoạn Giai đoạn 1 biến đổi dữ liệu nội suy trong vertex (bao gồm màu diffuse, màu specular và tọa độ texture) thành các thuộc tính màu của điểm ảnh. Gồm có các bước sau đây: Lấy mẫu texture (Sample texture). Lấy mẫu 1 hay nhiều texture Hòa màu (Blend colors). Kết hợp các màu trong thuộc tính của điểm ảnh chủ yếu là màu cơ bản (diffuse), màu phản chiếu (specular) với các màu lấy mẫu từ texture. Chương 2. Vertex Shader và Pixel Shader - 19 - Giai đoạn 2 sẽ chuyển điểm màu ở cuối giai đoạn 1 thành điểm màu cuối cùng được dựng lên trên màn hình. Quá trình này bao gồm các công đoạn sau đây: So sánh alpha (Alpha test). Tiến hành so sánh giá trị alpha để xem màu sắc của điểm ảnh có tham gia vào giá trị màu cuối cùng hay không. So sánh cập nhật vùng đệm độ sâu (Depth test). Cập nhật vùng đệm độ sâu (Depth buffer) bằng độ sâu của điểm ảnh nẽu điểm ảnh được vẽ. So sách stencil (Stencil test). Tiến hành kiểm tra stencil nếu điểm ảnh đợi vẽ. Tính toán sương mù (Per-pixel fog). Kết hợp giá trị sương mù với màu của điểm ảnh. Hòa màu dựa trên độ alpha (Alpha blend). Tiến hành kết hợp màu của điểm ảnh đang vẽ với màu của điểm ảnh tương ứng trên màn hình. Dither. Thực hiện chuẩn hóa màu. Hiệu chỉnh Gamma. Thực hiện hiệu chỉnh gamma trên điểm ảnh cuối cùng. Trong qui trình xử lý điểm ảnh ở trên, chỉ có giai đoạn 1 là có thể thay thế xử lý bằng Pixel Shader. Pixel Shader sau khi kết thúc sẽ trả giá trị màu tính được cho Fixed Function Pipeline. Ta hãy xem qua chi tiết xử lý trong giai đoạn 1 của Fixed Function Pipeline. Mô hình lý thuyết của Fixed Function Pipeline như sau: Hình 2-7 Mô hình xử lý điểm ảnh của Fixed Function trong giai đoạn 1 Chương 2. Vertex Shader và Pixel Shader - 20 - Dữ liệu texture (Texture Data). Là dữ liệu của texture lấy từ tập tin hay khung hình (Render Target). Sampler. Dùng để lấy mẫu texture. Có nghĩa là dùng tọa độ texture để tìm giá trị màu tương ứng tại tọa độ đó. Các bộ lọc texture (texture filtering) có thể làm ảnh hưởng đến chất lượng mẫu nhận được (trừ chế độ lọc theo điểm (point filtering)). Fixed Function Pipeline có tất cả 8 samplers. Cơ chế kết hợp đa texture (Multitexture Blender) bao gồm 8 tầng kết hợp (Blending Stage). Các tầng kết hợp được sắp chồng lên nhau sao cho đầu ra của đầu ra của tầng 0 trở thành đầu vào cho tầng 1, đầu ra của tầng 1 trở thành đầu vào cho tầng 2 và cứ thế. Mỗi tầng như vậy gọi là tầng texture (texture stage). Cả giai đoạn 1 này ta có thể sử dụng Pixel Shader để xử lý thay cho Fixed Function. Mô hình lý thuyết của Pixel Shader thay thế tương ứng với Fixed Function như sau. Hình 2-8 Mô hình xử lý điểm ảnh của Pixel Shader trong giai đoạn 1 Theo mô hình trên Pixel Shader cũng dùng các samplers để lấy mẫu texture, nhưng giờ đây cơ chế kết hợp đa texture (Multitexture Blender) đã được thực hiện Chương 2. Vertex Shader và Pixel Shader - 21 - ngay trong bản thân của Pixel Shader, bằng cách này các tác vụ kết hợp (blending) hoàn toàn có thể được lập trình lại. Một khi đã sử dụng Pixel Shader, ta không còn phải hiệu chỉnh các trạng thái của các tầng texture (Texture Stage States) để điều khiển cơ chế kết hợp đa texture nữa vì mọi thứ đã được làm trong Pixel Shader. Đây chính là sức mạnh của Pixel Shader: người lập trình không còn phải tốn nhiều công sức để thiết lập các trạng thái cho các tầng texture nữa, họ giờ đây hoàn toàn có thể tự lập trình ra các thuật toán mới để sử dụng, thậm chí hoàn toàn có thể trung chuyển các luồng dữ liệu từ vertex shader vào pixel shader (nếu dùng kết hợp cả 2 shader). Tuy nhiên vẫn còn những hạn chế do người lập trình vẫn chưa can thiệp được vào giai đoạn 2 của qui trình xử lý pixel, giai đoạn này vẫn còn bị sự kiểm soát của Fixed function Pipeline. Phần sau ta sẽ xem qua kiến trúc của máy ảo Pixel Shader 2.4.2. Máy ảo Pixel Shader Pixel Shader dùng các toán tử toán học để xử lý dữ liệu bên trong từng điểm ảnh để tính ra giá trị màu sắc cuối cùng của điểm ảnh. Hình 2-9 Mô hình lý thuyết của máy ảo Pixel Shader Chương 2. Vertex Shader và Pixel Shader - 22 - Dữ liệu trong mô hình được di chuyển từ trái sang phải. Pixel Shader sử dụng các thanh ghi (registers) để lưu trữ, quản lý các dữ liệu đầu vào (input), đầu ra (output), đồng thời thao tác trên chúng nhờ vào các vi lệnh được thực thi bởi đơn vị số học và luận lý (ALU). Pixel Shader khi thi hành sẽ biến đổi các thuộc tính bên trong của điểm ảnh (bao gồm vị trí, pháp tuyến, tọa độ texture, màu diffuse…) thành giá trị màu sắc của điểm đó. Các thanh ghi dữ liệu vào của Pixel Shader sẽ nhận dữ liệu vào là các giá trị nội suy của vertex. Chức năng của các texture sampler là dùng tọa độ texture từ các thanh ghi đầu vào để lấy mẫu texture và trả về giá trị màu lấy được. Tương tự như Vertex Shader, Pixel Shader sẽ ghi các giá trị kết quả vào các thanh ghi đầu ra (thường là giá trị màu sắc của điểm ảnh). Thanh ghi đầu ra sau khi nhận dữ liệu sẽ trả dữ liệu về cho Graphic Pipeline để xử lý tiếp giai đoạn 2. Sau đây là danh sách các loại thanh ghi được dùng trong Pixel Shader và chức năng của chúng. Thanh ghi dữ liệu vào (input registers) chứa dữ liệu đầu vào (nhận được từ quá trình xử lý đối tượng cơ sở (Primitive processing)). Thanh ghi hằng (constant registers) chứa các hằng số dùng trong ALU. Thanh ghi tạm (temporary registers) chứa các dữ liệu tạm thời. Thanh ghi dữ liệu ra (output registers) chứa kết quả tính toán của Pixel Shader. Thanh ghi điều khiển (Flow control registers) điều khiển thứ tự các vi lệnh được thực thi. Texture sampler dùng tọa độ texture để lấy mẫu texture sau đó trả về lại cho Shader. Các vi lệnh trong Pixel Shader chính là thành phần chính của Pixel Shader. Các vi lệnh đảm nhận việc thực thi một số tác vụ toán học trên dữ liệu ví dụ như tính tích vô hướng (dot product), nhân ma trận, tính vector đơn vị... Danh sách các loại thanh ghi cũng như các vi lệnh có thể kham thảo trong Direct3D SDK.
File đính kèm:
- thu_nghiem_3d_engine_2.pdf