• Thứ Sáu, 05/05/2006 08:02 (GMT+7)

    Bí mật về bộ lọc vật liệu

    Công nghệ 3D ngày nay phát triển một cách chóng mặt. Bên cạnh những công nghệ mới như "đổ bóng lập trình được", "ánh sáng động"..., ngay cả những kỹ thuật tưởng chừng như cơ bản là "dát" lớp vật liệu cũng không ngừng cải tiến. Bài viết này giới thiệu các kỹ thuật lọc vật liệu phổ biến hiện nay và cả các bí mật tối ưu được các nhà sản xuất sử dụng để tăng tốc các phép lọc đó.

    Công nghệ 3D ngày nay phát triển một cách chóng mặt. Bên cạnh những công nghệ mới như "đổ bóng lập trình được", "ánh sáng động"..., ngay cả những kỹ thuật tưởng chừng như cơ bản là "dát" lớp vật liệu (texture - hay còn gọi là vân bề mặt) cũng không ngừng cải tiến. Bài viết này giới thiệu các kỹ thuật lọc vật liệu (texture filtering) phổ biến hiện nay và cả các bí mật tối ưu được các nhà sản xuất sử dụng để tăng tốc các phép lọc đó.

    CÁC PHƯƠNG PHÁP LỌC

    Trước hết, chúng ta làm quen với một số khái niệm liên quan đến texture - nguồn của phép lọc:

    • Texture (vật liệu/vân bề mặt): là hình ảnh dùng để "lát" hay "dán" lên một bề mặt. Ví dụ: nền nhà bằng gỗ hay đá đều là các mặt phẳng như nhau, nhưng khác nhau bởi chất liệu "dát" lên.

    • Texel: một điểm ảnh (pixel) trên texture. Ta biết rằng texture chỉ là hình ảnh gốc. Còn hình ảnh kết quả trên màn hình được tạo ra từ việc lấy mẫu (sampling) trên texture. Điểm ảnh trên màn hình (hay frame buffer) được gọi là pixel, còn điểm ảnh được lấy mẫu trên texture gọi là texel (gọi tắt của texture pixel).

    • Texture filtering (lọc vật liệu): ám chỉ việc lấy mẫu (sample) các texel và thực hiện các phép toán trên các mẫu được lấy (thường là các phép tính trung bình có trọng số) để cho ra điểm ảnh kết quả. Texture filtering chỉ dùng để "đặt" hay "dán" (map) texture một cách hiệu quả nhất (về hiệu năng, về chất lượng...) lên bề mặt trong không gian ba chiều. Nó không bao gồm các thao tác làm thay đổi nội dung điểm ảnh như chiếu sáng, tạo bóng tối...

    1. Lấy mẫu thô

    Phương pháp lấy mẫu đơn giản nhất là ứng với mỗi điểm cần vẽ, ta tìm một điểm phù hợp nhất trên texture. Đây là phương pháp không dùng bộ lọc, được biết đến với cái tên nearest neighbour (láng giềng gần nhất) hay nearest-point sampling (lấy mẫu điểm gần nhất). Phương pháp này thể hiện rất nhiều nhược điểm nhưng cho tốc độ rất cao. Điển hình có thể kể ra đây hai nhược điểm:

    • Khi hình ảnh đích lớn hơn hình ảnh nguồn (chẳng hạn khi ta đứng sát một bờ tường): ta có cảm tưởng như các texel được phóng to ra và hình ảnh như là được ghép bởi các khối vuông thô thiển. Lí do là một texel được lấy mẫu cho nhiều pixel.

    • Khi hình ảnh đích nhỏ hơn hình ảnh nguồn (chẳng hạn khi ta tiến ra rất xa khỏi bờ tường): chắc chắn thông tin sẽ bị mất mát do số pixel đích ít hơn số texel, dẫn đến có texel không được lấy mẫu.

    2. Mipmap

    Mipmap là các biến thể theo các kích thước khác nhau của cùng 1 texture.

    Tại sao phải dùng đến các mipmap? Giả sử bạn đang đứng trên nền nhà bằng gạch, chắc chắn những viên gạch ở gần bạn trông sẽ "to" hơn theo phối cảnh, và do đó chi tiết hơn. Ở xa, sẽ có ít điểm hơn để hiển thị texture. Do đó mà texture bị co lại. Phép co sẽ làm mất những chi tiết quan trọng như đường viền xi măng của các viên gạch. Lí do là chỉ một số ít điểm trên texture được lấy mẫu (tùy vào loại bộ lọc bạn sử dụng mà độ mất mát khác nhau, tùy vào số texel được lấy mẫu cho một pixel). Tệ hơn nữa, khi bạn di chuyển trên nền gạch, các điểm lấy mẫu trên texture thay đổi theo. Điều này gây ra cảm giác nhiễu trên màn hình vì các điểm ảnh thay đổi liên tục từ texel này sang texel khác. Đặc biệt khi nền gạch có nhiều hoa văn với độ tương phản cao. Nhiễu còn thể hiện ở điểm các hoa văn trông như rời rạc, không liên tục do các texel được lấy mẫu một cách rời rạc.

    Các mipmap liên tiếp nhau có kích thước mỗi chiều chênh nhau 2 lần (như vậy ở texture nhỏ hơn, 1 điểm được tạo ra từ 4 điểm ở texture lớn hơn). Các card đồ hoạ ngày nay đều cho phép sinh mipmap tự động. Tức là chỉ cần cung cấp texture ở mức chi tiết nhất.

    Để kiểm tra việc sử dụng các mipmap, người ta dùng các Color Mipmap. Người ta tô các texture ở các mức khác nhau với các màu khác nhau. Do đó, khi hiển thị lên màn hình, ta có thể dễ dàng nhận thấy các texture khác nhau được lấy mẫu như thế nào.

    3. Linear Filtering (lọc tuyến tính)

    Lọc tuyến tính hiểu một cách nôm na là thay vì ta chuyển trực tiếp từ texel này sang texel khác khi lấy mẫu, các texel lại được chuyển qua dần dần một cách tuyến tính. Trong phép lọc tuyến tính, với mỗi chiều lọc, mỗi điểm ảnh được tạo ra từ trung bình có trọng số của hai texel.

    Phép lọc tuyến tính đơn giản nhất là Bilinear Filtering. Phép lọc này tạo ra pixel kết quả từ 4 texel gần nhau. Gọi là Bilinear (song tuyến tính) vì nó tuyến tính theo hai trục của texture.

    Hình sau đây cho thấy tác dụng của lọc tuyến tính khi thu nhỏ một trang web so với việc dùng phương pháp nearest-point sampling. Do có nhiều texel được lấy mẫu hơn nên nội dung mất mát giảm đi.

    Đối với việc phóng to một hình, lọc tuyến tính làm cho việc chuyển tiếp giữa các texel trở nên mượt mà, không bị cảm giác về các khối vuông.

    Trong đồ hoạ 3D và game hiện nay, gần như ta không còn gặp nearest neighbour nữa mà thay vào đó là các phương pháp lọc tiên tiến, phổ biến nhất là lọc tuyến tính.

    4. Trilinear Filtering (lọc tam tuyến tính)

    Như ta thấy, Bilinear filtering không dính dáng tới các mipmap. Nói cách khác, bilinear lọc từng texture trong mipmap một cách riêng rẽ. Do đó, ở chỗ chuyển tiếp giữa các mức mipmap lộ ra mép nối. Kết quả là trông hình ảnh đích như được tạo bởi các "băng" hay "dải" mipmap song song. Điều này đặc biệt khó chịu khi bạn di chuyển trong game. Có cảm giác như có những lớp hình ảnh luôn luôn chạy ở phía trước mặt bạn. Những đường nằm ngang cứ như muốn chấn vào mắt bạn.

    Các băng texture bị biến mất với trilinear, hình trở nên "mượt" hơn

    Trilinear filtering giải quyết vấn đề này bằng cách thực hiện lọc tuyến tính trên cả các mipmap, làm cho các texture được hoà trộn vào nhau trên hình đích. Trong các card đồ hoạ hiện nay, "chi phí” cho bilinear filtering rất thấp, gần như "miễn phí” (theo nghĩa không ảnh hưởng đến hiệu năng). Nhưng trilinear thì không như vậy, nó là một bộ lọc tốn kém. Vì nó không chỉ tăng gấp đôi số điểm lấy mẫu (từ 4 lên 8) mà còn yêu cầu phải xử lí nhiều texture cùng lúc. Do đó, hiện nay xuất hiện nhiều phép tối ưu để thực hiện trilinear hiệu quả hơn.

    5. Anisotropic filtering (lọc bất đẳng hướng)

    Trong thực tế đồ hoạ 3D, texture không đơn thuần được vẽ với hình dáng như ban đầu của nó. Do phối cảnh ba chiều, hình vuông hay hình chữ nhật (là dạng gốc của texture) trở thành hình bình hành, hình thang... Trong bộ lọc bất đẳng hướng, khác với Linear Filtering, các texel không được lấy mẫu theo một hình dạng đối xứng (đẳng hướng) mà theo một hình bất quy tắc được điều chỉnh tùy theo phối cảnh. Ta có thể hình dung mỗi pixel đích trên hình ảnh kết quả là một hình vuông. Tương ứng với hình vuông này có thể là hình chữ nhật, hình bình hành hay hình thang... trên texture. Dưới đây là một hình minh hoạ khi ánh xạ cùng một hình tròn nhỏ trên hình ảnh đích sang texture. Tùy vị trí của hình tròn mà các vùng tương ứng trên texture khác nhau.

    Anisotropic filtering tiến bộ hơn hẳn so với linear filtering vì nó bám sát hình dạng thực của điểm ảnh, cung cấp khả năng thể hiện thực và đầy đủ hơn nội dung của điểm ảnh, làm giảm thiểu mất mát nội dung trên hình kết quả. Anisotropic filtering có nhiều mức độ khác nhau (như ta thấy trong các thiết lập của driver và game), tùy thuộc vào số texel được lấy mẫu cho mỗi điểm ảnh đích. 1x lấy mẫu 4 texel (ta chưa xem xét đến mipmap), nên kết quả tương tự bilinear; 2x lấy mẫu 8 texel; 4x lấy 16; 8x lấy 32 và 16x (mức cao nhất hiện nay) lấy 64. Ta dễ dàng nhận thấy rằng càng lấy nhiều texel càng đòi hỏi texture chi tiết. Do đó, với các mức cao, mipmap càng bị đẩy sâu vào trong.

    Lọc bất đẳng hướng có thể kết hợp với bilinear hoặc trilinear thành bilinear anisotropic hoặc trilinear anisotropic. Với bilinear anisotropic, lọc diễn ra độc lập trên từng mức mipmap; với trilinear anisotropic, lọc được hoà trộn trên hai mức mipmap gần nhất.

    Tuy nhiên, cho đến hiện nay, lọc bất đẳng hướng vẫn là một "món" xa xỉ. Nó vừa yêu cầu lấy mẫu một số lượng lớn các điểm, lại vừa sử dụng phép tính có trọng số phức tạp. Do đó, nhiều phép tối ưu đã được thực hiện.

    BÍ MẬT CỦA TỐI ƯU

    1. Brilinear – Optimized Trilinear

    Hiểu một cách đơn giản thì "tối ưu" nghĩa là "làm ít hơn chứ không phải tốt hơn". Nhà thiết kế cố gắng giảm các thao tác được yêu cầu để cho kết quả chính xác nhằm làm cho phần cứng chạy nhanh hơn mà ít ảnh hưởng đến cảm nhận của người sử dụng (nó có thể đem lại kết quả mà hầu hết các điểm ảnh đều bị sai khác, nhưng tác dụng về mặt thị giác giữa hai hình ảnh lại chênh lệch không đáng kể).

    Phép tối ưu điển hình nhất và cũng được dùng phổ biến nhất là brilinear, một "phép lai" giữa trilinear với bilinear, thay thế cho trilinear. Mục đích chính của trilinear là làm mất đi các "dải" mipmap trên hình kết quả. Brilinear thu giảm vùng hòa trộn các mức mipmap vào sát các đường ranh giới và thực hiện bilinear hoàn toàn (tức chỉ dùng một mức mipmap) ở vùng chính giữa các "dải" này. Như vậy tức là giảm đáng kể việc sử dụng trilinear và thay thế bằng việc dùng bilinear. Ta có thể thấy rõ điều này qua hình minh hoạ dùng color mipmap dưới đây.

    Với Brilinear, khoảng chuyển tiếp mipmap bị thu hẹp và có một khoảng chỉ được lọc Bilinear

    Nói chung rất khó để phát hiện ra brilinear bằng mắt thường khi sử dụng các mipmap thực (chẳng hạn khi chơi game). Trong các game thông thường, brilinear có thể thu được đến hơn 30% hiệu năng so với full trilinear.

    Hầu hết các chip đồ hoạ mới hiện nay đều dùng phương pháp này. Ta có thể thấy tùy chọn sử dụng "trilinear optimizations" trong driver của các card đồ họa mới dòng GeForce.

    2. Tối ưu góc trong Anisotropic Filtering

    Thử tưởng tượng bạn đang đứng đối diện với một bức tường. Vì bức tường song song với màn hình nên nó là một hình "đẳng hướng" (các hướng được bảo toàn tỉ lệ). Do đó, việc lọc bất đẳng hướng trên bức tường không khác biệt so với lọc tuyến tính. Cũng giống như vậy với các mặt phẳng khác. Mỗi mặt phẳng có một độ bất đẳng hướng (tỉ lệ chênh lệch giữa các hướng) cực đại nhất định tùy thuộc vào góc nhìn mặt phẳng đó. Do vậy chỉ cần một mức lọc bất đẳng hướng nhất định mà không cần thiết phải dùng mức lọc cao hơn. Ví dụ nếu texture bị biến dạng ở tỉ lệ 1:2, 2xAF là đủ (đương nhiên ngay cả trên một mặt phẳng, tỉ lệ biến dạng của texture cũng liên tục thay đổi, như đã được chỉ ra trong hình vẽ trước). Tối ưu góc trong Anisotropic Filtering tận dụng điều này để nâng cao hiệu năng xử lí. Nó áp dụng các mức độ lọc khác nhau cho các góc khác nhau. Nghĩa là ngay cả khi bạn yêu cầu mức lọc 16x, sẽ có những góc nào đó mà phép lọc chỉ diễn ra ở mức 2x. Thực tế rất ít góc được thực hiện ở mức 16x hoàn toàn. Tối ưu góc được áp dụng trong tất cả các card đồ hoạ của ATI dòng 9xxx và các dòng X, trong các card NVIDIA GeForce FX 5xxx, 6xxx, 7xxx.

    3. Tối ưu theo mức mipmap

    Tối ưu theo mức mipmap nói một cách ngắn gọn là tùy thuộc vào mức mipmap khác nhau mà áp dụng các mức lọc khác nhau (chẳng hạn các mức lọc bất đẳng hướng). Do ở các mức mipmap thấp, texture đã giảm chi tiết đi rất nhiều. Nên người xem thường không nhận thấy việc thay đổi độ phức tạp trong phép lọc.

    4. Độ chính xác của các phép tính

    Số bit được sử dụng để lưu trữ các giá trị, các tham số, trọng số trong các phép tính ảnh hướng rất lớn đến độ chính xác của kết quả.

    Ví dụ dễ thấy nhất là số bit xác định trọng số trong phép lọc tuyến tính. Số bit này quyết định có bao nhiêu mức chuyển tiếp về màu sắc giữa hai mốc (hai màu của hai texel kề nhau). Vì hiện nay người ta chỉ dùng 8 bit cho mỗi thành phần màu, nên cũng chỉ cần tối đa 8 bit trọng số là có thể miêu tả đầy đủ các mức màu chuyển tiếp (256 mức). Đây là số bit được dùng trong các card GeForce. ATI sử dụng ít bit hơn. Với 6 bit, các card đồ hoạ của ATI chỉ có thể thể hiện được 64 mức chuyển tiếp, nghĩa là không đầy đủ hoàn toàn.Với ít mức chuyển tiếp, đoạn chuyển tiếp sẽ trở nên kém mượt mà.

    Tuy nhiên, thực tế rất khó thấy sự khác biệt này. Vì thông thường các texture chỉ được phóng to ở khoảng nhất định. Nghĩa là chỉ có một số ít điểm ảnh chuyển tiếp giữa hai texel, nên cũng chỉ cần một số ít mức chuyển tiếp. Dù vậy, phép lọc tuyến tính còn được dùng trong các thao tác tìm màu khác (chẳng hạn trong bộ đổ bóng điểm – pixel shading) nên với ít bit hơn, độ chính xác trong kết quả cuối cùng sẽ giảm. Đương nhiên, ít bit cũng có nghĩa là ít xử lí hơn và nhanh hơn.

    KIỂM NGHIỆM THỰC TẾ

    Có rất nhiều công cụ và phương pháp để kiểm nghiệm những vấn đề liên quan đến các phép lọc. Nhưng có lẽ dễ dàng và quen thuộc nhất với những người chơi game hoặc am hiểu về card đồ họa là phần mềm 3DMark của FutureMark. Công cụ này có chức năng "Filtering & AA" rất trực quan. Ở đây tôi xin giới thiệu vài hướng kiểm nghiệm lí thú để thấy vai trò và ảnh hưởng qua lại của các công nghệ kể trên bằng FutureMark 3DMark05.

    Chọn chức năng Filtering & AA của 3Dmark05

    Trước khi chạy chức năng này, bạn phải đảm bảo driver đồ họa không "ép" bất cứ thao tác nào như AntiAliasing hay Anisotropic Filtering. Nếu không, các thay đổi trong chương trình sẽ không "nghiệm".

    Ban đầu, bạn đặt Mag Filter, Min Filter về Point và MipMapping về None để xem Nearest-point sampling. Thử di chuyển, bạn sẽ thấy nhiễu. Sau đó, đưa cả ba thành Point, bạn sẽ thấy rất rõ các lớp Mipmap (nhất là khi di chuyển, đường phân định các lớp mipmap di chuyển "theo sát" bạn) và thấy luôn cả "tác hại" của việc không dùng lọc tuyến tính. Các khối vuông xuất hiện, đặc biệt khi bạn tăng mức chi tiết LOD bias lên (kéo xịch các mipmap lại gần bạn). Dùng chức năng Mipmap Coloring bạn thấy càng rõ. Bây giờ bạn chuyển Mag/Min Filter lên Linear, bạn có Bilinear. Các lớp mipmap vẫn còn rõ, nhưng nhiễu và khối vuông thì biến mất.

    Bây giờ bạn đặt cả ba tham số là Linear, bạn có Trilinear. Không còn các lớp mipmap nữa. Bạn có thể thử với Mipmap Coloring. Các lớp màu giờ đã chuyển tiếp hòa trộn vào nhau.

    Tiếp theo, bạn chuyển Mag/Min Filter lên Anisotropic (nếu Anisotropy level khác 1, đặt nó về 1 trước). Chẳng có khác biệt gì đáng kể cả. Như tôi đã trình bày, Anisotropic 1x gần giống với Linear Filtering do đều chỉ dùng 4 mẫu (không tính tới các lớp mipmap). Tăng dần Anisotropy Level, bạn dễ dàng phát hiện thật sự chỉ tồn tại các mức 1x, 2x, 4x, 8x, 16x. Các mức khác đều được làm tròn lên hoặc xuống các mức này. Sử dụng Mipmap Coloring để thấy rằng với mức lọc càng cao, mipmap càng bị đẩy vào sâu. Nếu card của bạn là "đời mới", sử dụng tối ưu góc trong Anisotropic Filtering, thì thật ngạc nhiên! Hầu hết các góc trong 16x và 4x được lọc giống hệt nhau!

    Hầu hết các góc AF 4x và 16x được lọc giống nhau

    Bây giờ thử nghiệm vì sao Anisotropic Filtering lại "hay" hơn Linear Filtering. Bạn đẩy Anisotropy Level lên 16x, và xem Bilinear/Trilinear Anisotropic Filtering (thay đổi Mipmap giữa Point và Linear). Sau đó chuyển về Trilinear (cả ba tham số đều là Linear). Bạn sẽ thấy hình rất mờ. Giảm LOD bias xuống để hình rõ hơn, bạn sẽ thấy hình "có vẻ” rõ hơn nhưng thực ra lại là nhiễu, nhất là khi bạn di chuyển.

    Nếu có card GeForce 6xxx, bạn có thể thử chức năng Trilinear Optimizations bằng thiết lập trong card đồ hoạ. Tuy nhiên thay đổi không trực tiếp trong lúc chạy chương trình nên không được rõ.

    Trên đây, tôi đã giới thiệu các phương pháp lọc vật liệu và cả các "bí kíp" mà các nhà sản xuất card đồ họa dùng để tăng hiệu năng đồ họa. Hi vọng bài viết có thể phần nào giúp các bạn có được cái nhìn rõ hơn về đồ họa 3D.

    Hồ Tất Thành - ĐH Công Nghệ – ĐHQG HN
    Email:
    hosongphi@yahoo.com
    Website: http://www.hotatthanh.fytvietnam.net


    -------------------------------------------------------
    Tham khảo:

    www.tomshardware.com
    msdn.microsoft.com
    www.3dcenter.de
    www.futuremark.com

    ID: A0604_125