2 điểm bởi GN⁺ 2024-03-01 | 1 bình luận | Chia sẻ qua WhatsApp
  • LUT (bảng tra cứu) là cách tham chiếu các giá trị đã được tính trước như một bảng, được dùng rộng rãi từ tô màu video ảnh nhiệt đen trắng cho đến biến thể đối tượng trong game và chỉnh màu video
  • Ví dụ WebGL cho thấy luồng đưa khung hình video lên GPU dưới dạng texture 2D, rồi áp dụng tinting, LUT 1D và LUT 3D trong Fragment Shader quyết định màu theo từng pixel
  • LUT 1D dùng giá trị độ sáng [0.0 - 1.0] làm tọa độ trong mảng màu để chuyển đầu vào đen trắng thành RGB; bộ lọc song tuyến tính của GPU giúp nội suy tự nhiên các giá trị trung gian ngay cả với LUT nhỏ
  • Như trường hợp Left 4 Dead của Valve, tinting và LUT được dùng để tạo các biến thể màu cho xe hơi, da zombie và trang phục trong giới hạn bộ nhớ texture
  • LUT làm phát sinh chi phí đọc texture bổ sung, nhưng là công cụ thực dụng để lưu trước các phép tính đắt như hiệu chỉnh gamma hoặc đưa quy trình chỉnh màu bên ngoài vào đồ họa thời gian thực

Vai trò của LUT trong lập trình đồ họa

  • Bảng tra cứu (LUT) là phương pháp tính trước các giá trị, lưu chúng vào hàng hoặc bảng, rồi tham chiếu khi cần
  • Trong lập trình đồ họa, cấu trúc đơn giản này dẫn tới nhiều hiệu ứng thị giác
    • Chuyển video đen trắng thành có màu
    • Áp dụng hiệu chỉnh màu và tạo phong cách màu
    • Tạo biến thể đối tượng trong video game một cách hiệu quả
  • Ví dụ sử dụng WebGL, nhưng kỹ thuật tương tự cũng áp dụng được cho DirectX, OpenGL, Vulkan, Unity và trực quan hóa dữ liệu khoa học
  • Video demo là bản capture từ Panasonic GH6 và camera ảnh nhiệt TESTO 890; quá trình xử lý không rời khỏi thiết bị mà được xử lý cục bộ trên GPU

Pipeline WebGL và tinting

  • Đầu ra của camera ảnh nhiệt là video đen trắng, và mỗi khung hình được truyền tới GPU qua WebGL dưới dạng texture 2D
  • Fragment Shader là đoạn mã quyết định màu cuối cùng cho từng fragment của đầu ra
    • Trong ví dụ, màu video tại vị trí hiện tại được đọc bằng texture2D(video, tex).rgb
    • Đầu ra cuối cùng của WebGL 1.0 được ghi vào gl_FragColor dưới dạng RGBA
  • Tinting là cách nhân màu của texture với một màu cụ thể để phủ sắc thái màu
    • Trong ví dụ, màu cam được nhân bằng videoColor * vec3(1.0, 0.5, 0.0)
    • Màu trắng trở thành màu cam, còn màu đen vẫn là màu đen vì được nhân với 0
  • Trong ngữ cảnh này, chi phí phép nhân của tinting có thể khó đo
    • Chi phí lấy texture từ bộ nhớ lớn hơn phép nhân rất nhiều
    • Khi nhiều luồng chạy song song, phép nhân cho pixel khác có thể được thực hiện trong lúc chờ đọc texture của một pixel
    • Đây là giải thích về khác biệt mà tinting tạo ra, không có nghĩa là toàn bộ tối ưu hiệu năng đã hoàn tất

Valve sử dụng tinting

  • Left 4 Dead của Valve Software dùng tinting để tạo biến thể xe hơi
  • Cách tạo texture riêng cho từng loại xe và từng màu có thể vượt quá ngân sách bộ nhớ texture
  • Valve dùng thêm texture mask để tinting vùng sơn xe bằng màu khác nhau cho từng instance
    • Một texture màu được chia sẻ giữa 3 mẫu xe
    • Với chi phí của hai texture, có thể tạo 4 mẫu xe và số biến thể màu gần như không giới hạn
  • Trong Source Engine, không chỉ xe hơi mà về bản chất mọi thứ đều có thể tinting

Dùng LUT 1D để chuyển giá trị đen trắng thành màu

  • LUT 1D là một mảng số; nếu là ảnh RGB thì đó là mảng một chiều gồm các màu
  • Giá trị độ sáng của video đen trắng được dùng làm tọa độ trục X của LUT để lấy màu
    • Giá trị độ sáng video nằm trong phạm vi [0.0 - 1.0]
    • Màu đen 0.0 được ánh xạ tới màu bên trái LUT, màu trắng 1.0 tới màu bên phải LUT
    • Các giá trị trung gian được ánh xạ tới màu ở vị trí tương ứng
  • WebGL 1.0 không có texture 1D nên dùng texture 2D cao 1px
    • Mã ví dụ có dạng texture2D(lut, vec2(videoColor, 0.5))
    • Đầu vào là giá trị 1D và đầu ra là RGB, nên cấu trúc là “vector 1D vào, vector 3D ra”
  • Bộ lọc song tuyến tính của GPU tự động nội suy giá trị trung gian khi đọc texture
    • Video đen trắng 8-bit có 256 mức độ sáng
    • Ngay cả khi LUT 1D chỉ rộng 32 pixel, truy cập giữa các pixel vẫn được nội suy tuyến tính
    • Chỉ với thông tin của 8 pixel cũng có thể tạo kết quả gần với gradient nhiều màu rộng 256 pixel

Chọn colormap và tính đồng đều theo cảm nhận

  • Ví dụ có kèm danh sách các colormap do matplotlib hỗ trợ được xuất ra thành LUT 1D
  • Nếu dữ liệu không có cấu trúc cụ thể, nên dùng colormap đồng đều theo cảm nhận hoặc đặt màu dựa trên loại đó
    • Họ viridis là ví dụ tiêu biểu
  • Colormap đồng đều theo cảm nhận vẫn giữ vùng lạnh tối và vùng nóng sáng ngay cả khi xuất ra đen trắng
  • Những colormap như jet, chủ yếu chỉ đổi màu sắc (hue) và bỏ qua độ sáng theo cảm nhận, không đảm bảo thuộc tính này
  • Việc người có bất thường về thị giác màu cũng có thể diễn giải dữ liệu đúng là một tiêu chí quan trọng khi chọn colormap

Hiệu năng của LUT 1D và xấp xỉ đa thức

  • Chi phí của LUT 1D nhỏ nhìn chung có thể thấp, nhưng có nhiều điểm cần cân nhắc hơn tinting
  • Mối lo hiệu năng chính là đọc texture phụ thuộc
    • Kết quả của lần đọc texture đầu tiên quyết định tọa độ cho lần đọc texture thứ hai
    • Trong lập trình đồ họa, đây là mẫu có thể loại bỏ một phần các đường đi có thể tối ưu
  • GPU có texture cache, và LUT nhỏ có thể nằm trong cache nên chi phí đọc LUT có thể rất thấp
  • Đánh giá hiệu năng chi tiết cần công cụ phân tích theo từng nền tảng
    • Nvidia NSight cung cấp phân tích hiệu năng theo từng giai đoạn shader, nhưng không hỗ trợ OpenGL
  • Nếu triển khai colormap bằng xấp xỉ đa thức, không cần xử lý texture LUT
    • Xấp xỉ viridis trên ShaderToy của Matt Zucker được viết theo dạng Horner’s method
    • Màu được tính bằng các phép multiply-add dạng c0+t*(c1+t*(c2+t*(c3+t*(c4+t*(c5+t*c6)))))
    • Việc nó có thực sự nhanh hơn LUT hay không khó kết luận nếu không phân tích theo từng nền tảng

Biến thể zombie trong Left 4 Dead 2

  • Left 4 Dead 2 dùng LUT cho các biến thể màu da và trang phục, nơi chỉ tinting đơn giản là chưa đủ
  • Tinting đơn giản có thể không cung cấp đủ sự đa dạng về độ chói của màu
  • Với da và trang phục, một vài LUT được chọn ngẫu nhiên để tạo nhiều biến thể màu
    • Artist chọn color ramp phù hợp để đưa vào game cuối cùng
    • Từ một texture có thể tạo cả biến thể vest sáng và vest tối
  • Bài trình bày đầy đủ liên quan có thể xem tại Shading a Bigger Better Sequel của GDC
  • “Exclusive Masking” là cách đặt hai phạm vi texture trong cùng một kênh
    • Texture 1 dùng phạm vi 0-128
    • Texture 2 dùng phạm vi 128-256
    • Cái giá phải trả là giảm độ chính xác màu

LUT 1D lưu trước phép tính

  • LUT 1D cũng có thể được dùng làm cache cho phép tính đắt trong lập trình đồ họa
  • Hiệu chỉnh gamma là ví dụ tiêu biểu
    • Nếu không dùng xấp xỉ, cần hàm pow()
    • Đặc biệt trên GPU cũ, pow() có thể là lệnh đắt
    • Nếu dùng đường cong từng đoạn chuẩn sRGB, còn có thêm đường rẽ nhánh
  • Tính trước chuyển đổi gamma bằng LUT 1D giúp bỏ qua phép tính theo từng pixel
    • Trong trường hợp này, cấu trúc là “vector 1D vào, vector 1D ra”
    • LUT 1D có thể xuất tối đa 4 kênh màu
  • Redshift là một ví dụ phần mềm tinting màn hình sang màu cam vào ban đêm để giảm mỏi mắt
    • Thay đổi Gamma Ramp cho từng kênh Red, Green, Blue của màn hình
    • Tính trước Kelvin Warmth → RGB và phần tính Gamma bổ sung thành 3 LUT 1D
    • Phần triển khai liên quan nằm trong mã nguồn Redshift
  • Cách này không ảnh hưởng hiệu năng vì việc remapping diễn ra ở màn hình chứ không phải card đồ họa, nhưng hỗ trợ giao diện phần cứng hiện nay thường chập chờn hoặc hỏng
    • Graphics stack của Raspberry Pi từng mất hỗ trợ liên quan trong một bản cập nhật mới
    • Microsoft cảnh báo về việc dùng SetDeviceGammaRamp

LUT 3D: remap toàn bộ không gian RGB

  • LUT 3D biểu diễn toàn bộ không gian RGB như một khối lập phương và remap mọi màu khả dĩ
  • Nó chuyển vector RGB đầu vào ba chiều thành vector RGB đầu ra ba chiều, nên có cấu trúc “vector 3D vào, vector 3D ra”
  • Áp dụng LUT 1D cho từng kênh Red, Green, Blue có thể thay đổi cân bằng màu
  • LUT 3D cần thiết cho các phép biến đổi cần tổ hợp RGB đầu vào
    • Thay đổi độ bão hòa
    • Thay đổi màu sắc (hue)
    • Điều chỉnh màu cụ thể
    • Tách màu
  • LUT 3D thường có dạng khối lập phương; trong game nó được lưu ở dạng strip hoặc square, còn trong công cụ biên tập video được dùng dưới dạng file .cube “Iridas/Adobe”

Triển khai LUT 3D trong WebGL 1.0

  • Video trong ví dụ được quay bằng Panasonic GH6 với profile màu Panasonic V-Log
  • V-Log là profile log giữ được dải động rộng hơn và có định nghĩa Gamut cùng Gamma rõ ràng
  • WebGL 1.0 không hỗ trợ texture 3D, nên việc đọc texture 3D được triển khai bằng hai lần đọc texture 2D và nội suy
  • Mã ví dụ cũ từng có lỗi tính trục Z của khối lập phương khiến màu bị dịch sang xanh lam, và đã được sửa vào năm 2019
  • Để giữ tương thích trong WebGL 1.0, OpenGLES 2 và OpenGL 2.1 khi không có OES_texture_3D, cần dùng phiên bản mới nhất của mã lấy mẫu texture 3D

Đưa quy trình chỉnh màu vào bằng LUT 3D

  • Các hiệu chỉnh áp dụng lên LUT 3D sẽ được áp dụng nguyên vẹn lên video hoặc cảnh đồ họa đi qua LUT đó
  • Trong ví dụ, video V-Log và LUT được đưa vào DaVinci Resolve để xử lý
    • Áp dụng V-Log to V-709 3D-LUT của Panasonic
    • Hiệu chỉnh độ tương phản và white point để màu trắng trở thành full-bright
    • Xuất lại LUT đã được hiệu chỉnh
  • Video thực tế vẫn là bản gốc, còn chỉnh màu được áp dụng thời gian thực trong WebGL thông qua LUT
  • LUT tải lên phải giữ cùng kích thước
    • Ràng buộc của ví dụ là 1024px × 32px
    • Phải giữ dạng khối lập phương 32³px

Cách ngành game dùng LUT 3D

  • Dùng LUT 3D để tạo phong cách màu cho game bằng công cụ bên ngoài là workflow chuẩn, nổi tiếng trong ngành video game
  • Quy trình thông thường như sau
    • Chụp screenshot của cảnh cần chỉnh màu
    • Mở screenshot cùng LUT 3D đã khởi tạo trong một công cụ như Photoshop
    • Áp dụng cùng một hiệu chỉnh màu cho screenshot và LUT
    • Cắt phần LUT 3D và xuất ra
  • Left 4 Dead cũng dùng cách tương tự
  • Có thể dùng tự do các công cụ chỉnh màu của Photoshop, nhưng không thể dùng bộ lọc làm thay đổi quan hệ giữa nhiều pixel
    • Các loại convolution như blur, sharpen, emboss có thể làm nhòe màu đã remap và tạo kết quả ngoài dự đoán

Nướng chỉnh màu phức tạp vào một LUT

  • Các công cụ chỉnh màu như DaVinci Resolve có thể tạo các phép chuyển đổi màu và color grade phức tạp rồi xuất ra LUT 3D
  • Ví dụ áp dụng LUT Kodak 2383 nhằm tạo film print look
    • Chuyển video V-Log gamma sang Cineon Film Log
    • Chuyển không gian màu sang Rec.709
    • Áp dụng mô phỏng phim và chuyển gamma trở lại Rec.709
    • Cuối cùng điều chỉnh white point
  • Có thể nướng các chuyển đổi chi tiết phức tạp vào một LUT rồi đưa vào ứng dụng đồ họa, thay vì tự triển khai trực tiếp
  • Video ví dụ dùng định dạng nén mạnh 8-bit để tương thích với bài viết, nhưng thông thường đây là công việc thực hiện trên footage 10-bit
  • Kích thước LUT được dùng nhỏ hơn nhiều so với tưởng tượng
    • V-Log to V-709 3D-LUT chính thức của Panasonic có kích thước 33³px
    • LUT giám sát trong camera của Panasonic dùng 17³px
    • Ngay cả các camera cinema của Panasonic ở tầm giá năm chữ số USD cũng dùng 17³px

Ví dụ LUT ngoài đồ họa

  • LUT còn được dùng ngoài lập trình đồ họa
  • LUT cũng được sử dụng trong trường hợp port Tomb Raider lên Game Boy Advance
  • Bản port engine mã nguồn mở OpenLara xử lý nhiều phần bằng phần mềm vì Game Boy Advance không có tính năng 3D
  • Một trong số đó là LUT triển khai phép chia số nguyên
  • LUT này được đặt ở phần đầu không gian địa chỉ ROM để bỏ qua load instruction

1 bình luận

 
GN⁺ 2024-03-01
Các ý kiến trên Hacker News
  • Nếu không có bảng tra cứu thì có lẽ hoàn toàn không thể triển khai hiệu ứng này: https://twitter.com/zeta0134/status/1756988843851383181
    Điểm cốt lõi là dùng hai bảng tra cứu. Bảng lớn lưu thông tin chiếu sáng hình tròn trong một bán kính có thể cấu hình quanh người chơi, và mỗi bán kính có nguyên một bảng riêng. Bảng thứ hai chứa thứ tự giả ngẫu nhiên của các hàng nền. Mỗi lần routine chiếu sáng đuốc được gọi, chỉ có đủ thời gian cập nhật 1/20 màn hình, nhưng nếu làm thứ tự hơi ngẫu nhiên thì rìa trông mượt hơn và che được kiểu quét raster vốn sẽ lộ ra. Thứ tự này là một “grab bag” để các hàng không bị bỏ đói trong quá trình cập nhật, vì tính toán thời gian thực quá chậm nên phải dùng bảng

    • Trông khá ngầu, đồ họa đẹp hơn nhiều so với bất kỳ game NES nào mình nhớ, nhìn như đồ họa tầm SNES. Có vẻ chạy trên trình giả lập, không biết trình giả lập đó có giới hạn hiệu năng về mức NES không
    • Trông đúng là một game rất tuyệt. Không biết có lấy cảm hứng từ Crypt of the Necrodancer không. Đó là một trong những game mình thích. Mình từng nghĩ nếu cơ chế như vậy được phát minh thời đó thì NES hay các console cũ khác có thể xử lý đến mức nào, và có vẻ đây là minh chứng rằng điều đó khả thi
    • Việc cập nhật 1/20 hoạt động tốt là vì khi ngọn đèn di chuyển, nó tạo ảo giác các ô tile dần hiện ra một cách tự nhiên. Thật hay khi có thể đánh lừa mắt bằng hiệu ứng như vậy
    • Luôn thú vị khi thấy game cho cùng một console ngày càng đẹp hơn rất nhiều khi mọi người học được cách lập trình tốt hơn. Ví dụ như Mario 1 và 3, hoặc hai game Zelda trên N64
    • Từ khóa để tìm cho phần “dùng thứ tự ngẫu nhiên như một grab bag để các hàng không bị bỏ đói trong cập nhật” có lẽ là quasirandom
  • Hiệu ứng bảng tra cứu đầu tiên thật sự gây ấn tượng với mình là cách dùng để tạo đường hầm texture
    Có một bảng tra cứu cho biết góc và khoảng cách từ tâm màn hình cho từng pixel trên màn hình, rồi dùng nó để chọn texel nào sẽ đặt vào từng vị trí pixel. Nó trông như đang di chuyển trong một đường hầm hình học 3D, nhưng chi phí rất thấp nên pico cũng làm được: https://www.lexaloffle.com/bbs/?pid=63818
    Ban đầu mình nghĩ Stardust đã dùng hiệu ứng này, nhưng vừa tìm lại thì thực ra nó chỉ phát một animation 6 frame lặp lại ở nền: https://codetapper.com/amiga/sprite-tricks/stardust/

    • Nếu xem bảng màu như một bảng tra cứu, thì palette cycling cũng rất phổ biến và có vẻ khá liên quan
    • Một cách dùng nguyên lý này ở mức cao cấp là parallax occlusion mapping (POM). Thậm chí còn có thể tự đổ bóng
      https://web.engr.oregonstate.edu/~mjb/cs557/Projects/Papers/Parallax_Occlusion_Mapping.pdf
    • Nếu muốn xem nó hoạt động thế nào, bên dưới demo có một nút Code ▽ nhỏ
    • Nhìn vào tính đối xứng trong một số trường hợp cụ thể có thể giúp tìm ra lời giải tiện lợi
  • Có video nói về cách Wind Waker dùng nhiều LUT để tạo diện mạo độc đáo. BoTW và ToTK cũng dùng cùng kỹ thuật
    https://www.youtube.com/watch?v=mnxs6CR6Zrk

  • Mình là tác giả bài viết. Nếu có câu hỏi thì mình có thể trả lời

    • Các ví dụ dùng LUT rất hay, và thật vui khi thấy một bài giải thích gọn gàng những nội dung này. Việc dùng WebGL và cho phép tự tải dữ liệu lên cũng tốt
      Tuy nhiên cách bài viết giới thiệu color grading bằng LUT hơi khiến mình ngạc nhiên. Trong bài, nó trông như một giải pháp ngách thú vị mà L4D2 đã dùng, nhưng thực tế từ lâu đây đã là chuẩn trong ngành và được dùng trong mọi game mình từng làm. Từ game AAA như NFS (2015) đến các game indie lớn như Lost in Random đều như vậy
    • Bài viết hay, và mình muốn bổ sung một chút cho phần cuối. Game Boy Advance có hỗ trợ phép chia số nguyên ở một mức nào đó, nhưng không được tăng tốc bằng phần cứng [1]. Mô hình LUT rất có thể là vì lý do hiệu năng, và quyết định đó có vẻ hợp lý
      [1] https://www.copetti.org/writings/consoles/game-boy-advance/#operating-system
    • Vì lỗi chính tả mà mình đã bối rối khá lâu, tưởng có một thư viện vẽ đồ thị khác
      “Here is every single colormap that matlibplot supports,...”
    • Quá nhiều GIF động nên khó chịu và gây phân tâm. Mấy meme boomer nhạt kiểu thập niên 2010 cũng không cần thiết. GIF sặc sỡ cứ bật ra liên tục khiến việc đọc bài trở nên khó khăn
  • Ngay cả trong lĩnh vực quy trình nghiệp vụ nhàm chán, thứ này cũng hữu ích đến mức đáng ngạc nhiên
    Nhiều khi có thể đơn giản hóa một codebase đầy câu điều kiện thành các bảng tra cứu gọn gàng. Có vẻ không phải lúc nào người ta cũng nghĩ tới, vì ngay cả thứ trông đơn giản cũng có thể thành bảng tra cứu 50.000 hàng. Với người dùng cuối thì có thể trông nhiều, nhưng máy tính thì không bận tâm lắm. Hơn nữa bảng tra cứu có tính lặp lại nên thường dễ quản lý, và kể cả khi không dễ thì vẫn đáng dùng. Người dùng cuối cũng có thể cấu hình mà không cần thay đổi code. Nhìn chung đây là một khái niệm đặc biệt hữu ích cho nhiều kịch bản thường xuyên xuất hiện khi code business logic

    • Làm như vậy rồi cuối cùng sẽ sinh ra DSL
    • Bảng tra cứu được double-buffer cơ đấy!
  • Các game retro dùng bảng tra cứu rất nhiều. Khi đó tốc độ bộ nhớ rất nhanh còn bộ xử lý thì chậm, nên việc đẩy càng nhiều phép tính càng tốt vào bảng là hợp lý. Càng làm khéo thì càng có thể tạo ra game hào nhoáng hơn

    • Không phải lúc nào cũng vậy; có lẽ còn tùy retro là nói đến nền tảng nào. Kaze Emanuar trên YouTube làm khá nhiều phát triển cho N64, và khoảng một nửa các câu chuyện tối ưu hóa của anh ấy là về việc bus bộ nhớ ảnh hưởng thế nào đến đủ kiểu tối ưu. Trong Mario 64, bảng tra cứu sẵn có cho hàm sin đã được thay bằng công thức xấp xỉ, vì công thức xấp xỉ nhanh hơn và đủ chính xác. Chính xác hơn là hai công thức xấp xỉ khác nhau cho các mục đích khác nhau
      Tôi thích kênh đó. Anh ấy đã chỉnh toàn bộ mã của Mario 64 để mod của mình chạy nhanh hơn, đạt 60FPS ổn định [0]
      [0] https://www.youtube.com/watch?v=t_rzYnXEQlE
    • Tôi nhớ thời người ta giới hạn độ chính xác của góc quay theo đơn vị 360/256 độ để nhét vào một byte, rồi dùng giá trị đó làm chỉ số cho bảng tra cứu lượng giác :)
  • Nếu bạn phải xử lý nhiều LUT, tôi đang làm một ứng dụng Mac để xử lý khoa học màu sắc nâng cao và các tác vụ chuyển đổi: https://videovillage.com/lattice

  • Trước đây tôi từng tìm hiểu một chút về giới homebrew NES, và thấy trong một game tên Bobl có hiệu ứng vật lý đáng kinh ngạc, vượt xa mức hệ thống có thể tính toán. Hóa ra đó là bảng tra cứu, và tôi nhận ra rằng bằng một công cụ đơn giản có thể khiến nó trông như một quá trình rất phức tạp
    https://morphcatgames.itch.io/bobl

    • Tôi không phủ nhận hiệu ứng đó ấn tượng, nhưng nếu ý bạn là gợn sóng bề mặt hay sóng mao dẫn, tôi tự hỏi liệu việc tính toán một automaton tế bào một chiều theo thời gian thực có thật sự khó với NES đến vậy không
  • A Podcast Of Unnecessary Detail đã có một tập nói về bản port Doom lên SNES và cách LUT được dùng cho các hàm lượng giác. Bối cảnh là SNES không có bộ xử lý đồ họa
    https://festivalofthespokennerd.com/podcast/series-3-episode-4/
    https://github.com/RandalLinden/DOOM-FX

    • Nói “SNES không có bộ xử lý đồ họa” là hoàn toàn sai. Ngay cả NES cũng có. Ngoài CPU của SNES là bản sao Motorola 65c816, PPU (picture processing unit) là một chip tùy biến cung cấp nhiều bố cục để xuất nền dạng tile và sprite khi TV CRT vẽ từng scanline về mặt vật lý
      Nó cũng có thể xoay và co giãn nền. Đó là Mode 7 — cứ nghĩ đến Mario Kart — và còn hỗ trợ độ trong suốt phần cứng thấy trong nhiều game. Hơn nữa, trong các trường hợp như Doom và Starfox, cartridge còn có chip Super FX để xử lý tính toán 3D. Vì vậy với các tựa game cụ thể đó, thực tế là đang xử lý tới hai bộ xử lý đồ họa
      Có một series Retro Game Mechanics Explained nói về phần cứng SNES cực kỳ hay và chi tiết đến mức đau đầu:
      https://www.youtube.com/watch?v=57ibhDU2SAI&list=PLHQ0utQyFw5KCcj1ljIhExH_lvGwfn6GV&index=1
  • Những cách dùng LUT tôi nhớ mình từng viết là tán xạ khí quyển, tô màu sprite, ống ngắm nhìn đêm, ống ngắm FLIR, hiệu ứng “nguồn video” đen trắng, hiệu ứng glitch, shading heightmap, hệ số điểm alpha cho vệt phụt khí thải tàu vũ trụ, heatmap thời gian rê chuột của khách truy cập website, hiệu ứng tinh thể, và cuối cùng là tô màu hậu kỳ trong không gian màu thô
    LUT là cách trực quan hóa một mảng các giá trị đã biết sẵn, và hữu ích đến đáng kinh ngạc

    • “Tô màu sprite” cơ à, bọn trẻ thời nay quên hết sprite dựa trên palette rồi! Cụm “palette swap” từ đâu mà ra chứ? ;)
      http://www.effectgames.com/demos/canvascycle/
      Xbox đời đầu xử lý cái này không tốt và Photoshop cũng không hỗ trợ nên nó mất dần độ phổ biến. Nhưng phần cứng hiện đại hoàn toàn xử lý được palette swap tạo bằng AESprite