Sau khi tính được các đường Silhouette công việc tiếp theo là phải tính bóng đổ theo khối bóng được tại ra bởi các đường Silhouette. Z-Pass là một thuật toán sử dụng để tính bóng dựa vào các đường này, thuật toán này sử dụng kết hợp hai bộ đệm (Depth buffer, và Stencil buffer). Chúng ta có thể mô tả tư tưởng chính của thuật toán như sau:
Hình 2.13. Tư tưởng chính của Z-Pass.
Tại điểm nhìn ta xây dựng các tia nhìn vào cảnh giá trị khởi tạo cho mỗi tia nhìn là 0 và khi tia nhìn đến một khối bóng thì giá trị của tia nhìn được tăng lên 1 đơn vị, tương tự như vậy khi nó đi khỏi khối bóng thì giá trị của tia nhìn được giảm đi 1 đơn vị. Tia nhìn sẽ kết thúc khi nó gặp bề mặt của một đối tượng hay cụ thể
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
43
hơn giá trị depth tại bề mặt đến - đi của khối bóng tại vị trí cắt tia nhìn lớn hơn giá trị hiện tại của depth bufer. Ta có thể hình dung trực quan hơn thông qua “Hình 2.13”. [2]
Khi ta đã tạo được lưới các đa giác bao ngoài bóng khối. Chúng ta phải thực sự vẽ bóng của vật thể ra, hay nói chính xác là vẽ ra vật thể cùng với bóng của nó. Để làm được việc đó ta phải xác định được một pixel có nằm trong vùng bóng khối đó hay không. Thuật toán xác định một pixel có nằm trong vùng bóng khối đó hay không khá đơn giản. Tư tưởng của nó là, nối điểm cần kiểm tra với điểm đặt camera (mắt nhìn). Nếu số mặt trước và số mặt sau của bóng khối mà nó cắt bằng nhau thì điểm đó không nằm trong vùng bóng khối. Nếu nó cắt số mặt trước của bóng khối nhiều hơn số mặt sau mà nó cắt thì có nghĩa là điểm đó nằm trong vùng bóng khối.
Để xác định xem đoạn đó cắt bao nhiêu mặt trước, bao nhiêu mặt sau ta sẽ dùng một bộ đếm cho mỗi điểm cần kiểm tra, mà sẽ tăng lên 1 đơn vị khi nó đi xuyên qua một mặt trước và giảm đi một đơn vị nếu nó đi xuyên qua một mặt sau của bóng khối. Khi đó nếu bộ đếm cho giá trị bằng 0 thì điểm đó không nằm trong phần bóng, Còn nếu nó lớn hơn 0 thì có nghĩa là điểm này nằm trong vùng bóng và sẽ không được được vẽ ra.
Và Stencil Buffer sẽ thực hiện điều đó. Stencil Buffer sẽ cung cấp cho mỗi pixel trên màn hình một “bộ đếm” và chúng ta có thể tăng và giảm nó khi pixel đó được ghi vào trong Frame Buffer. Sau đó chúng ta hoàn toàn có thể kiểm tra bộ đếm đó để xác định xem điểm đó sẽ được ghi ra màn hình hay không.
Các bước thực hiện như sau:
Bƣớc 1: Tính đường Silhouette, việc tính đường Silhouette chỉ cần thực hiện một lần và chỉ cần cập nhật khi có sự thay đổi vị trí của đối tượng hoặc nguồn sáng trong cảnh. Việc này được thực hiện bởi thuật toán đã được mô tả ở phần trên
Bƣớc 2: Vẽ mô hình bằng các thuật toán tô bóng cục bộ, trong đó có sử dụng
Depth buffer để xét xem một điểm có hay không được cập nhật vào bộ đểm màu sắc
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
44
Bƣớc 3: Thiết lập các giá trị ban đầu cho Stencil Buffer là 0. Tắt việc cập nhật các giá trị vào các bộ đệm khác chỉ để các giá trị được cập nhật vào Stencil
Buffer. Tắt hết các hiệu ứng môi trường, để chế độ tô bóng về chế độ đơn giản nhất
nhằm tăng tốc độ render. Thiết lập Depth Test là Depth-Pass.
Bƣớc 4: Vẽ các đa giác của khối bóng có hướng vector pháp tuyến mà tích vô hướng của nó với hướng nhìn > 0. Với lựa chọn cập nhật Stencil Buffer là tăng thêm một đơn vị.
Bƣớc 5: Vẽ các đa giác của khối bóng có hướng vector pháp tuyến mà tích vô hướng của nó với hướng nhìn < 0. Với lựa chọn cập nhật Stencil Buffer là giảm đi một đơn vị.
Khối bóng được tạo thành từ các đa giác tạo bởi từng đoạn thằng thành phần của đường Silhouette và hướng nguồn sáng (ra đến một giá trị vô cùng lớn). Và các đa giác đậy hai đầu đầu các theo đường Silhouette. Các đa giác đậy hai đầu có thể xây dựng được bằng hai cách: một là sử dụng chính các đa giác cấu thành bề mặt đối tượng (các đa giác có hướng pháp tuyến mà tích vô hướng giữa pháp tuyến đó với hướng nguồn sáng đến đa giác là > 0) hai là sử dụng các đa giác được tạo thành khi tam giác hóa đường Silhouette. Tùy vào từng yêu cầu cụ thể có thể cân nhắc việc sử dụng hai cách trên.
Bƣớc 6: Sau khi vẽ hoàn tất các khối bóng ta được dữ liệu trong bộ đệm
Stencil Buffer là các giá trị, các giá trị này phản ánh tính chất của từng điểm. Với những điểm có giá trị > 0 có nghĩa nó có bóng đổ và ngược lại. Việc còn lại là kết hợp các giá trị trên bộ đệm này với bộ đệm màu sắc là kết qua từ bước hai.
Thuật toán sẽ được mô tả bằng mã giả như sau:
Procedure IN_SHADOW_TEST // Z-pass
For {tất cả các vật thể cần đổ bóng} do
- Xây dựng danh sách các cạnh viền.
- Tính toán các tứ giác bao quanh bóng khối dựa trên các cạnh viền và từ vị trí của nguồn sáng.
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
45
For {Tất cả các mặt trước của bóng khối nhìn từ vị trí của điểm nhìn} do
if Depth test passes then
- Tăng giá trị Stencil Buffer.
End if
End for
For {Tất cả các mặt sau của bóng khối nhìn từ vị trí của điểm nhìn} do
if Depth test passes then
- Giảm giá trị Stencil Buffer.
End if
End for
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
46
2.15. .
Số hóa bởi Trung tâm Học liệu http://www.lrc-tnu.edu.vn/
47
2.17. .
Nhìn chung Z-Pass là một thuật toán vẽ bóng khối cho tốc độ tốt nhất vì nó hạn chế được một số lượng lớn các điểm cần vẽ bởi Depth buffer. Tuy nhiên Z-Pass
có lỗi khi điểm nhìn nằm trong một hay nhiều bóng khối, lỗi này được khắc phục trong thuật toán Z-Fail [2]