Saturday, 6 November 2010

[XNA]Shader - Bộ tạo bóng


XNA sử dụng bộ tạo bóng (shader) để chuyển đổi dữ liệu đỉnh (vertex) sang điểm ảnh (pixel).
Phương pháp này sẽ giúp thể hiện đẹp hơn bởi vì shader xử lý đồ họa trên card đồ họa. Shader cung cấp khả năng để tạo các đỉnh hiển thị theo ý muốn. Shader được dùng để thao tác với tất cả thuộc tính của đỉnh như màu sắc, vị trí, bề mặt… Ngoài ra, shader cho phép thực hiện việc tạo hiệu ứng ánh sáng, pha trộn hiệu ứng như chế độ trong suốt, đa bề mặt...

    Kênh đồ hoạ - Graphics Pipeline


Kênh đồ hoạ mô tả quá trình chuyển đổi các dữ liệu đầu vào ở dạng đỉnh và các hình cơ bản thành dữ liệu đầu ra dạng điểm ảnh.
Các bộ tạo bóng đỉnh (vertex shader) và bộ tạo bóng điểm ảnh (pixel shader) đóng vai trò chủ chốt trong quá trình xử lý này.
1 Vertex shader
Là một phần của shader biểu diễn hoạt động trên mỗi đỉnh nhận từ mã nguồn XNA. Chúng ta có thể dùng vertex shader để chỉnh sửa và vẽ vài thuộc tính của đỉnh. Loại shader này áp dụng các phép biến đổi cho dữ liệu đầu vào dạng đỉnh. Khi các đỉnh đã biến đổi được truyền qua cho shader, dữ liệu đầu ra (sẽ không được nhìn thấy đối với người xem) sẽ được cắt xén và các mặt sau được loại bỏ. Thao tác này gọi là Chọn lọc (Culling). Quá trình quét được thực hiện để chuyển đổi dữ liệu của vector sang dạng ảnh đầu ra. Việc nội suy cũng được thực thi giữa các đỉnh để phân phối đồng đều dữ liệu của đỉnh giữa các toạ độ. Trong bộ tạo bóng điểm ảnh, việc tô màu và tạo bề mặt được áp dụng trước khi xuất các điểm ảnh lên màn hình.
2 Pixel shaders
Chuyển dữ liệu đỉnh từ vertex shader sang dữ liệu điểm ảnh có màu. Pixel shader không thể chỉnh sửa vị trí hoặc thông tin vector pháp tuyến nhưng nó có thể biểu diễn hoạt động trên mỗi điểm ảnh để hiện thực hiệu ứng ánh sáng, màu sắc, bề mặt, pha trộn.
3. Tóm tắt hoạt động
 

  High Level Shader Language (HLSL)


Đối với những trò chơi XNA, hầu hết shader được viết bằng High Level Shader Language (HLSL) của Microsoft. HLSL tương tự cú pháp của ngôn ngữ C, và bởi vì ngôn ngữ C# cũng giống ngôn ngữ C về các loại dữ liệu, các cấu trúc điều kiện, vòng lặp. Do đó, những cú pháp khác dùng trong mã nguồn của HLSL cũng dễ dàng để chuyển đổi trong mã nguồn XNA. Ta có thể viết shader bằng ngôn ngữ assembly, nhưng cú pháp assembly thì khó đọc và không tương thích với card đồ họa. Bởi vì HLSL và XNA được thiết kế để hiện thực trên Xbox 360 và cả hai được tạo bởi Microsoft nên ta sẽ viết mã shader bằng HLSL.
Ban đầu, các nhà lập trình trò chơi chỉ viết shader bằng ngôn ngữ assembly nhưng mã assembly có một số vấn đề đối với card video. Card đồ họa sản xuất như NVIDIA, AMD và nhiều loại khác có tập hợp chỉ dẫn mã assembly tương tự nhau, nhưng sự khác biệt giữa những card video thỉnh thoảng làm shader không tương thích. Vì điều này, các trò chơi sử dụng mã shader duy nhất với nhà cung cấp card đồ họa có thể không hài hòa với những máy dùng những loại card màn hình khác. Nếu chỉ phát triển trên Xbox 360, chúng ta có thể sử dụng những đặc tính mới nhất của HLSL. Nếu viết mã nguồn để chạy trên máy tính, ta nên xem xét sự khác nhau của card đồ họa khi viết shader.
Trên XNA, Microsoft yêu cầu card đồ họa của máy tính hỗ trợ ít nhất chế độ shader 2.0. Tuy nhiên, shader được viết dùng chế độ shader 1.1 cũng có thể chạy trên Xbox 360.

   Cấu trúc shader


 1) Bộ tạo bóng đỉnh – Vertex Shader
Bộ tạo bóng đỉnh là một phần của shader, nó thực hiện các xử lý tính toán trên mỗi vector nhận được từ mã nguồn XNA. Có thể dùng vertext shader để thay đổi và vẽ bất kỳ thuộc tính đỉnh nào. Nó có thể được dùng cho việc “chiếu sáng theo đỉnh”, thay đổi vị trí, màu sắc hoặc điều chỉnh các toạ độ ảnh.
Ví dụ, vertex shader có thể thay đổi thông tin này bằng cách dùng các đầu vào khác nhau như phép biến đổi và phép lọc. Khi việc thay đổi cho mỗi đỉnh hoàn tất, các dữ liệu ra như màu sắc, và bề mặt sẽ được gửi tới một bộ pixel shader để xử lý thêm. Vị trí và pháp tuyến có thể được truyền cho pixel shader nếu có nhu cầu tính toán cho thông tin này. Tuy nhiên, vị trí và pháp tuyến không hề thay đổi khi nó rời khỏi vertex shader.
Cuối cùng, vertex shader phải kết xuất dữ liệu vị trí. Các thành phần được truyền qua cho pixel shader được nội suy từ hai bên đa giác trước khi chúng được gửi đến pixel shader.
 2) Bộ tạo bóng điểm ảnh - Pixel shader
Có nhiệm vụ chuyển dữ liệu đỉnh từ vertex shader sang thành các điểm ảnh có màu sắc. Pixel shader không thể thao tác với vị trí và pháp tuyến nhưng nó có thể thực hiện các phép tính trên điểm ảnh để hiện thực các hiệu ứng như chiếu sáng, tô màu, tạo bề mặt, pha trộn… các thao tác trên điểm ảnh tốn kém hơn các thao tác trên đỉnh. Tuy nhiên, đối với việc chiếu sáng thì ta nên dùng pixel shader sẽ cho hiệu ứng chiếu sáng tuyệt vời hơn. Khi việc xử lý trong pixel shader xong, pixel shader xuất các pixel có màu ra card đồ hoạ cho một pixel tại một thời điểm.
   
 3)Technique và Pass
 Một technique định nghĩa các vertex shader và pixel shader được dùng trong mỗi pass thông qua quá trình vẽ các điểm ảnh. Trong nhiều trường hợp, công việc vẽ được thực hiện trên một pass. Tuy nhiên ta có thể chỉ định nhiều pass nếu phải hiện thực các bề mặt trộn lại với nhau (multitexturing)

  Các loại dữ liệu shader


iểu dữ liệu trong XNA
Kiểu dữ liệu của ngôn ngữ HLSL
Matrix
float4x4
Texture2D
Texture
struct  MyStruct
{public MyStruct(int i) {} };
Struct
int
Int
float
Float
Vector2
float2 // mảng với 2 phần tử
Vector3
float3 // mảng với 3 phần tử
Vector4
float4 // mảng với 4 phần tử
Color
float3 hoặc float4

   Tham chiếu đến shader trong XNA


Để sử dụng shader, ứng dụng XNA phải nạp và tham chiếu đến shader. XNA thực hiện công việc này khá dễ dàng với lớp Effect cung cấp vài phương thức để nạp (loading) và biên dịch (compiling) shader. Mã nguồn XNA có thể chỉnh sửa biến shader toàn cục thông qua lớpEffectParameter.
1) Hiệu ứng (Effect)
Đối tượng Effect cho phép nạp và biên dịch mã shader, hoàn thành vài sự thay đổi biến mà ta làm với shader, gửi dữ liệu đỉnh từ mã XNA đến shader. Lớp Effect được dùng để khai báo đối tượng hiệu ứng:
private Effect        effect;
Khi shader được tham chiếu trong mã nguồn từ Solution Explorer, ta có thể sử dụng phương thức Load() để đọc nó. Những tập tin  HLSL shader có  phần mở rộng là *.fx. Tuy nhiên, khi shader được tham chiếu trong Solution Explorer, phần mở rộng .fx bị cắt bỏ từ tên tập tin trong câu lệnh nạp từ mã nguồn:
Effect = content.Load<Effect> ( @“đường_dẫn\tên_shader”);
2) EffectParamete
Đối tượng EffectParameter cho phép thiết lập biến toàn cục trong shader từ mã nguồn XNA. Lớp EffectParameter được dùng khi khai báo đối tượng:
private EffectParameter effectParameter;
Khi định nghĩa đối tượng EffectParameter trong đoạn mã XNA, chúng ta có thể dùng nó để tham chiếu biến shader toàn cục.
Khi đối tượng EffectParameter được khai báo và khởi tạo, thiết lập biến trong shader là xử lý gồm hai bước. Thứ nhất, ta gán giá trị với phương thức SetValue:
effectParameter.SetValue( DataValue );
Tham số sử dụng trong SetValue( ) phải nối kiểu dữ liệu của biến thiết lập. Khi giá trị được  thiết lập, ta phải kết thúc sự thay đổi trạng thái của shader bằng cách sử dụng phương thức CommitChanges( ):
Effect.CommitChanges( );

No comments:

Post a Comment