2.3 HIỆU ỨNG BÓNG ĐỔ
2.3.1 Tạo bóng đổ bằng bóng khối
a. Giới thiê ̣u
Thuâ ̣t toán ta ̣o bóng đổ bằng kỹ thuâ ̣t sử du ̣ng bóng khối được đề xuất đầu tiên bởi Frank Crow vào năm 1977. Theo đó Ông ta vẽ mô ̣t khối bi ̣ che , lấp ánh sáng bởi vâ ̣t ta ̣o bóng đổ. Mọi vật thể nằm trong khối đó đƣợc coi là nằm trong vùng đổ bóng.
Bóng khối là một vùng không gian đƣợc kéo dài từ hình bao tạo bởi đối tƣợng và nguồn sáng (occluder light) theo hướ ng của ánh sáng . Bất kỳ điểm nào nằm trong đó đều thuô ̣c vùng bóng đổ của vật thể với nguốn sáng “Hình 2.13”.
Hình 2.13. Bóng đổ theo bóng khối
Quan sát hình vẽ ta thấy rằng những khu vực nào nằm trong vùng bóng khối tạo bởi đối tƣợng với nguồn sáng là vùng có bóng đổ, những vùng nằm ngoài các khối bóng là những vùng không có bóng đổ.
b. Tìm đường bao của đối tượng theo nguồn sáng
Thuật toán tính bóng đổ dựa vào bóng khối lấy cơ sở là khối bao của đối tƣợng theo nguồn sáng. Vậy công việc đầu tiên là phải tính đƣợc khối bao tạo bởi đối tƣợng với nguồn sáng (khối bóng). Trong trường hợp đơn giản nhất xét một tam giác như trong “Hình 2.14”.
Hình 2.14. Khối bao của tam (ABC) giác với nguồn sáng điểm L
Khối bao là khu vực đƣợc in đậm, ta thấy rằng khối bao của một tam giác là một khối được tạo bởi toàn bộ cạnh của tam giác đó và các đường nối với nguồn sáng.
Như vậy, khi xét một đối tượng, trong trường hợp đơn giản nhất khối bao của đối tƣợng sẽ là tập hợp các khối bao của từng đa giác cấu thành đối tƣợng. Với cách xây dựng khối bao nhƣ vậy thì công việc xây dựng các khối bao cho đối tƣợng sẽ không cần giải quyết vì mỗi đa giác sẽ xác định ngay đƣợc các cạnh của nó. Tuy vậy, với việc lựa chọn khối bao nhƣ thế số lƣợng khối bao cấu thành khối bao của đối tƣợng sẽ là rất lớn, dẫn tới thời gian tính toán bóng đổ là rất lớn do đó người ta thường lựa chọn khối bao cho đối tượng là khối bao cấu thành từ đường bao của đối tượng theo nguồn sáng.
Vậy tại sao chỉ cần sử dụng đường bao của đối tượng theo hướng nguồn sáng và việc tính các đường bao này như thế nào?. Xét hình vẽ sau “Hình 2.15”:
B
A
C 1.1.1.a.1.1.1 L
(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03
46
Hình 2.15. Đường bao của một đa giác trong không gian 2D Ta thấy rằng các điểm C,D,E mặc nhiên nằm trong khu vực có bóng đổ vì nó không nhìn thấy nguồn sáng, các cạnh che toàn bộ là các cạnh BA, AF, nếu không tính không gian của chính đối tƣợng cạnh đại điện cho đa giác ABCDEF với nguồn sáng chỉ là BF mà thôi. Xét tính chất tại các điểm B và điểm F ta thấy rằng các cạnh tạo bởi đỉnh B là AB, BC có hướng vector pháp tuyến ngược nhau so với vector hướng ánh sáng tới tại điểm B hay cụ thể là: dot(NAB,lB)0
và dot(NBC,lB)0
, với dot là hàm tích vô hướng, N là vector pháp tuyến của cạnh, l là hướng nguồn sáng tại mỗi điểm.
Mở rộng hơn ta có thể tìm được đường bao của một đối tượng trong không gian 3D theo nguồn sáng. Thuật toán cụ thể có thể trình bày sơ lƣợc nhƣ sau:
c. Thuật toán tìm đường occluder light
Bước 1: Lấy danh sách các cạnh của đối tượng Bước 2: Xét với mỗi cạnh
Nếu tại cạnh đó chỉ có một đa giác liên đới thì bổ sung cạnh đó vào danh sách các đường (occluder light).
Nếu có hai hoặc nhiều hơn hai đa giác tại cạnh đang xét thì xét nếu tồn tại một cặp đa giác sao cho dot(Nci,l)*dot(Ncj,l)0
, với ci là đa giác thứ i chứa cạnh c, cj là đa giác thứ j chứa cạnh c, thì bổ sung cạnh đó vào danh sách các đường (occluder light).
Bước 3: Sau khi tìm được danh sách các cạnh là đường (occluder light) tiến hành nối các cạnh này lại để được các đường bao. Việc nối các cạnh này dựa vào chỉ số của từng cạnh.
Sau các bước này chúng ta đã có danh sách các đường (occluder light, người ta còn gọi các đường này là đường Silhouette) cho đối tượng, chúng là các đường đóng.
1.1.1.a.1.1.2 L
1.1.1.a.1.1.3 A
1.1.1.a.1.1.4 E 1.1.1.a.1.1.5 D 1.1.1.a.1.1.6 C
1.1.1.a.1.1.7 F
Khi thực hiện thuật toán tạo bóng đổ bằng bóng khối ta phải vẽ kín cả hai đầu nhƣ trong “Hình 2.15” ta phải vẽ cả đường BAF, tuy nhiên trong môt số trường hợp đơn giản ta chỉ cần vẽ cạnh BF để giảm số lượng đa giác cần vẽ. Vậy với mỗi tập đường Silhouette chúng ta phải tiến hành tam giác hóa trong trường hợp muốn giảm thiểu tối đa việc vẽ khối bóng để tăng tốc độ hiển thị.
Ngoài cách tính đường Silhouette như trên, chúng ta cũng có thể xây dựng đường Silhouette dựa vào bản đồ chiều sâu “depthmap” lấy được bằng cách coi nguồn sáng nhƣ là một điểm nhìn và tiến hành render chỉ lấy bản đồ chiều sâu từ điểm nhìn đó. Công việc tính các đường Silhouette dựa theo depthmap sử dụng thuần các kỹ thuật trích biên, tách ngưỡng trong xử lý ảnh 2D. Nhìn chung ưu điểm của phương pháp này là dễ cho việc tính toán, tổ chức lưu trữ, nhưng nhược điểm lớn nhất của phương pháp này là tốc độ do phải xử lý trên ảnh, mặt khác kích thước ảnh cũng ảnh hưởng đến chất lượng của khối bóng do không có sự ánh xạ hoàn toàn gữa không gian ảnh và không gian đối tƣợng.
d. Thuật toán tạo bóng đổ Z-Pass
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:
(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03
48
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ể 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.16”.
e. Thuật toán sẽ được mô tả bằng mã giả 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 “a”.
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 Color buffer. Sau bước này Depth buffer được sử dụng cho các bước tiếp theo
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.
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 các thuật toán Z-P+ và Z-Fail.
f. Thuật toán tạo bóng đổ Z-P+
Z-P+ là một thuật toán tạo bóng đổ dựa vào bòng khối, nó đƣợc thiết kế dựa trên thuật toán Z-Pass nhằm khắc phục nhƣợc điểm của Z-Pass. Ta đã biết ở phần trên Z-Pass sẽ có lỗi khi điểm nhìn nằm trong một hay nhiều khối bóng. Đề khắc phục điều này người ta vẽ thêm mặt cắt của khối bóng với mặt phẳng nhìn, như thể hiện trong “Hình 2.17”.
Hình 2.17. Bóng khối trong thuật toán Zp+
Vậy thuật toán Zp+ là không có sự khác biệt lớn so với thuật toán Z-Pass điểm khác biệt duy nhất là ở chỗ khi vẽ bóng khối thì chúng ta phải xét xem bóng khối đó
(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03
50
tương đương với Z-Pass. Đáng tiếc việc tính va chạm giữa khối bóng với mặt phằng chiếu lại là công việc không đơn giản, và không thể thực hiện đƣợc bằng GPU mà phải thực hiện bằng CPU do đó chi phí thời gian cho Zp+ là không thực sự tốt hơn so với Z-Fail. Vì lí do thuật toán này tương tự như Z-Pass chúng tôi sẽ không trình bày cụ thể thuật toán này.
g. Thuật toán tạo bóng đổ Z-Fail
Z-Fail là thuật toán tạo bóng đổ bằng bóng khối phổ biến nhất hiện nay, nó một mặt khắc phục đƣợc nhƣợc điểm chính của Z-Pass không thể hiện đƣợc dúng khi điểm nhìn nằm trong khối bóng, nhƣng đồng thời cũng không yêu cầu nhiều tính toán khác trên CPU, hầu nhƣ nó chỉ yêu cầu nhiều hơn thời gian tính toán trên GPU.
Hình 2.18. Tư tưởng của Z-Fail
Tư tưởng chính của Z-Fail được thể hiện thông qua “Hình 2.18”. Từ điểm nhìn vẽ các đường thẳng vào không gian, chỉ xét đường thẳng từ điểm nó đã va chạm với bề mặt của mội đối tượng nào đó, khi đường thẳng gặp một mặt phẳng có hướng vector pháp tuyến ngược với hướng nhìn (tích vô hướng của hai vector là nhỏ hơn 0) thì tăng giá trị lên 1, và mặt phẳng ở phía khia thì trừ giá trị đi 1 đơn vị. Kết quả những đường thẳng có giá trị lớn hơn 0 thì có nghĩa điểm trên tia nhìn đó là điểm thuộc khu vƣc đổ bóng (điểm có bóng đổ).
Với tư tưởng như vậy cách thể hiện của Z-Fail trái ngược với Z-Pass. Nó chỉ kiểm tra những điểm trên bề mặt của khối bóng có khoảng cách tới điểm nhìn là lớn hơn giá trị trong bộ đệm Z-Buffer.
Thuật toán được thể hiện dưới dạng mã giả như sau:
Bước 1: Tính đường Silhouette
Bước 2: Vẽ mô hình bằng các thuật toán tô bóng cục bộ
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-Fail.
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 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 phap 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 các 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 đ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 là kết qua từ bước hai.
Nhìn chung Z-Fail phải thực hiện cập nhật Stencil Buffer nhiều hơn so với
(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03(LUAN.van.THAC.si).nghien.cuu.mot.so.ky.thuat.chieu.sang.trong.trung.bay.ao.luan.van.ths.cong.nghe.thong.tin.60.47.01.03
52
phục lỗi của Z-Pass, các cải tiến xung quanh việc tam giác hóa đường Silhouette nhằm thể hiện đúng nhất bóng của đối tƣợng mà không phải vẽ cả phần nửa bề mặt đối tượng (phần có vector pháp tuyến mà tích vô hướng của nó với hướng ánh sáng là lớn hơn 0). Xa hơn nữa trong việc nâng cao chất lượng bóng người ta cũng có những phương pháp để tạo ra bóng mềm (một loại bóng đổ gần với thực tiến hơn vì mức độ bóng trên đối tƣợng là liên tục) từ bóng khối [9], [21],[20], [25].