2 điểm bởi GN⁺ 2025-01-26 | 1 bình luận | Chia sẻ qua WhatsApp
  • Đây là một trò chơi Snake sử dụng subpixel bên trong pixel của màn hình làm các ô chơi, nhỏ đến mức cần kính hiển vi mới có thể chơi đúng nghĩa
  • Dựa trên JavaScript Snake hiện có, trò chơi kết hợp màu theo vị trí cột và mix-blend-mode: lighten để khiến nhiều subpixel trong cùng một pixel vật lý có thể cùng lúc hiển thị
  • Để hoạt động bình thường, cần cấu trúc subpixel RGB stripe và sự căn chỉnh giữa pixel CSS với pixel vật lý; trên iMac tác giả chỉnh bằng cách thu nhỏ, nhưng trên iPad thì không hiệu quả
  • Khi kiểm tra bằng kính hiển vi, màu xanh lục sRGB không chỉ bật riêng subpixel xanh lục mà còn bật cả đỏ và xanh dương; nguyên nhân được xác định là do dải màu rộng hơn của các màn hình hiện đại
  • Khi dùng Lab color, tác giả có thể tách riêng subpixel đỏ và xanh lục trên iMac, nhưng tính tương thích lâu dài kém vì cấu trúc pixel đang dần rời xa kiểu RGB stripe

Dùng subpixel làm bàn chơi

  • Trò chơi Snake này không dùng pixel thông thường của màn hình mà dùng các subpixel đỏ, xanh lục và xanh dương bên trong pixel như các ô chơi
  • Khi nhìn gần, pixel trên màn hình được cấu thành từ nhiều subpixel; khi nhìn xa, mắt người sẽ thấy các ánh sáng này hòa trộn thành một màu duy nhất
  • Trong lúc chụp nhiều màn hình bằng ống kính macro nhận được vào Giáng sinh, tác giả xác nhận rằng mỗi màn hình có hình dạng subpixel khác nhau
    • Dạng Chevron
    • Dạng stripe
    • Mẫu diamond
  • Sự khác biệt trong cách sắp xếp này được gọi là hình học subpixel, và chiếc iMac của tác giả dùng cấu trúc RGB stripe

Cách triển khai và những giới hạn lộ ra dưới kính hiển vi

  • Việc chuyển bản JavaScript Snake làm từ 15 năm trước sang phiên bản cho subpixel về cơ bản khá đơn giản
    • Giảm số cột của trò chơi
    • Hiển thị khối Snake ở cột nhất định bằng một màu nhất định
    • Áp dụng mix-blend-mode: lighten để dù có nhiều khối nằm trong cùng một pixel thì tất cả vẫn hiện ra
  • Để thực sự hoạt động, cần thỏa mãn hai điều kiện
    • Người dùng phải dùng màn hình có cấu trúc subpixel RGB stripe
    • Pixel CSS của trình duyệt phải được căn chỉnh với pixel vật lý
  • Việc căn chỉnh pixel CSS có thể xử lý bằng cách thu nhỏ, nhưng cách này chỉ hoạt động trên iMac và thất bại trên iPad
  • Việc triển khai hoàn thành rất nhanh, nhưng vì không thể kiểm chứng bằng mắt thường việc hiển thị ở cấp độ subpixel, tác giả đã dùng kính hiển vi giá rẻ mua online để chụp lại màn hình thực tế
  • Dưới kính hiển vi, khi hiển thị màu xanh lục, không chỉ subpixel xanh lục bật lên mà nhiều subpixel khác cũng cùng sáng
    • Lúc đầu tác giả nghi là lỗi, nhưng mã nguồn không có vấn đề gì
    • Khi kiểm tra màu xanh lục đơn sắc, trên iMac không chỉ subpixel xanh lục mà cả đỏ và xanh dương cũng bật
    • Trên điện thoại, màu xanh lục cũng làm subpixel đỏ sáng nhẹ
  • Sau khi hỏi người vận hành trang về hình học subpixel, tác giả biết nguyên nhân là sự khác biệt giữa chuẩn sRGB và dải màu của các màn hình hiện đại
    • sRGB được tạo ra vào thời kỳ màn hình có hiệu năng và dải màu hẹp hơn
    • Trên màn hình hiện đại, nếu chỉ bật riêng subpixel xanh lục thì có thể tạo ra màu bão hòa hơn cả xanh lục sRGB
    • Để hiển thị chính xác màu xanh lục sRGB mong muốn, cần thêm đỏ, và trong một số trường hợp cả xanh dương
  • Khi đổi định nghĩa màu RGB sang Lab color, tác giả có thể tận dụng không gian màu lớn hơn để tách riêng subpixel đỏ và xanh lục trên iMac
  • Tuy vậy, vì hình học pixel đang dần rời xa RGB stripe và subpixel trong tương lai có thể phát sáng theo cách hoàn toàn khác hiện nay, nên phương pháp này khó duy trì lâu dài

1 bình luận

 
GN⁺ 2025-01-26
Ý kiến trên Hacker News
  • Đọc bài Subpixel Zoo được liên kết mới biết PenTile vẫn còn được dùng cực kỳ rộng rãi
    Màn hình PenTile đầu tiên tôi từng dùng là Motorola Droid 4, và nó thật sự rất tệ. Chữ nhỏ khó đọc tùy theo màu chữ và màu nền, còn khoảng cách giữa các màu lớn đến mức các vùng đơn sắc đỏ/xanh lá/xanh dương trông như bàn cờ
    Cảm giác đó đã có từ trước khi VR phổ biến và thuật ngữ hiệu ứng cửa lưới trở nên thông dụng. Vì vậy tôi ngạc nhiên khi PenTile vẫn còn được dùng; có lẽ nó đã tốt hơn, hoặc khoảng cách giữa các subpixel đã nhỏ lại, hoặc độ phân giải và mật độ điểm ảnh cao hơn đã che đi những nhược điểm từng thấy trên Droid 4

    • Các màn hình PenTile đời đầu có cách sắp xếp khác: [https://en.wikipedia.org/wiki/PenTile_matrix_family#/media/F...](https://en.wikipedia.org/wiki/PenTile_matrix_family#/media/File:Nexus_one_screen_microscope.jpg)
      Theo trục ngang/dọc là thứ tự xanh dương, xanh lá, đỏ, xanh lá, nên một subpixel đỏ cách xa bằng hai subpixel xanh lá và một subpixel xanh dương
      Các màn hình PenTile hiện đại thường dùng bố cục tam giác: https://static1.xdaimages.com/wordpress/wp-content/uploads/w...
      Tôi không phải chuyên gia render chữ, nhưng với bố cục tam giác này, có vẻ có thể đặt các tổ hợp subpixel RGB gần nhau hơn nhiều so với bố cục tuyến tính. Hơn nữa Droid 4 cũng có độ phân giải thấp. Apple đã lên 330ppi vào năm 2010, còn Droid 4 năm 2012 chỉ 275ppi, nên ngay cả theo chuẩn thời đó cũng là thấp, và PenTile giảm một phần ba số subpixel hẳn còn làm nó tệ hơn
      Galaxy S25 hiện nay là 416ppi, iPhone 16 là 460ppi, nên số điểm ảnh nhiều hơn hẳn. Mật độ điểm ảnh có lẽ là yếu tố ảnh hưởng lớn nhất, nhưng bố cục tam giác của màn hình hiện đại cũng có vẻ giúp ích
    • Chính xác là vì thế. Độ phân giải của Droid 4 thấp đến mức thấy được bố cục subpixel, còn màn hình mới có mật độ cao nên hoàn toàn không thấy subpixel
  • Con rắn di chuyển kỳ lạ là vì subpixel không phải hình vuông
    Để người dùng nhìn trên màn hình thật thấy tốc độ như nhau theo mọi hướng, có lẽ nên tăng tốc độ di chuyển ngang so với dọc khi tính theo subpixel

  • Là người mê game arcade retro đến mức tự làm một cabinet giả lập cao cấp với CRT analog RGB quad-sync 27 inch, tôi rất thích video này
    Ngay khoảnh khắc tác giả nói gặp vấn đề với pixel xanh lá, tôi lập tức cảm thấy mình sắp học được điều thú vị. Những thứ như cấu trúc subpixel, sắc độ phosphor là các hố thỏ càng đào càng thú vị, và vẫn rất liên quan đến các màn hình ngày nay như OLED, QLED
    Khi chơi arcade kinh điển thập niên 80–90 hoặc game console retro, chơi trên CRT tốt hơn nhiều và gần với bản gốc hơn. Nếu chơi bằng giả lập, chỉ cần bật pixel shader giả lập CRT là được (CRT Royale khá tốt). Pixel art này được các lập trình viên và họa sĩ thời đó tạo ra với chủ ý tận dụng sự hòa trộn màu và khử răng cưa tự nhiên của scanline trên CRT. Nó đáng được xem theo cách vốn được dự định: https://i.redd.it/9fmozdvt6vya1.jpg

    • Là người thích phần cứng retro thật, một cabinet như vậy trông rất tuyệt. Làm tôi muốn bỏ cả đống xu vào chơi trong nhiều giờ
      Bài này khiến tôi rơi vào hố thỏ mô phỏng CRT, và thực sự có thứ như thế này
      https://github.com/blurbusters/crt-beam-simulator
    • Muốn nghe thêm về cấu hình của bạn. Giá mà có blog nào ghi chép lại thì tốt
    • Tôi không thích cảm giác LCD mờ nhòe. Trông như ai đó hack file .ini để đẩy khử răng cưa cao gấp 4 lần giới hạn rồi đặt một tấm lưới chống côn trùng trước màn hình
      Tôi chơi game vào thời chuyển từ CRT sang LCD, và không ai thích đồ họa trên CRT hơn cả
      Cú tụt lùi thật sự là khi game chuyển từ PC sang console và server riêng chết đi. Ngày xưa tôi chọn server độ trễ 10ms, còn bây giờ người ta coi 60–100ms trở lên cũng ổn
    • Lập luận “phải xem theo cách vốn được dự định” thật khó tin. Tôi lớn lên với game trên CRT, nhưng các CRT thực tế khác nhau rất nhiều về độ sắc nét, màu sắc, artifact, và còn khác cực lớn tùy theo cách xuất/nhập tín hiệu video
      Nó khác nhau tùy bạn nối vào TV, màn hình rẻ tiền hay màn hình đắt tiền; điều có thể nói chắc chỉ là CRT mờ hơn. Ảnh so sánh được đưa ra gây hiểu nhầm vì độ sáng hoàn toàn khác nhau. Có vẻ phía LCD/LED không dùng gamma đúng
      Dùng một CRT bất kỳ thì màu da rất có thể cũng ngả xanh lá, và artifact màu của CRT có thể nghiêm trọng. Tôi hiểu việc làm mờ hình trong emulator để giảm răng cưa, và hiệu ứng CRT retro cũng là một phần trang trí thú vị, nhưng tôi khó chấp nhận luận điểm đó là “hình ảnh game được dự định”. Nó giống như nói phải nghe nhạc thập niên 90 bằng loa rẻ tiền giữa tiếng ồn đường phố thì mới là “đúng ý đồ”. Đó chỉ là thứ tốt nhất có thể vào thời đó mà thôi
    • Có vẻ đó là những hình ảnh tương tự nhưng khác nhau
      Tôi lớn lên cùng CRT, nhưng rất ít game “trông đẹp hơn” trên CRT; phần lớn chỉ là những game dùng interlace để tạo hiệu ứng nhấp nháy. Thêm nữa, súng ánh sáng cần CRT vì vấn đề timing
      Ngoài ra CRT giống vinyl. Có người viện đủ lý do để nói nó tốt hơn, nhưng thực tế không phải vậy
  • Thật sự thú vị. Tôi học được nhiều về không gian màu và cách nó áp dụng vào subpixel, rất mừng là đã xem video
    Về mặt gameplay, có lẽ nên làm bàn chơi lớn hơn và hiệu chỉnh tốc độ của con rắn khi đi qua từng subpixel. Khi di chuyển trái/phải, từ R sang G có quãng ngang nhỏ hơn từ B sang R, còn di chuyển dọc thì mỗi bước lại rất lớn so với di chuyển ngang
    Có lẽ có thể giải quyết khá dễ bằng cách điều chỉnh tốc độ từng bước animation theo tỷ lệ tùy vị trí trong phổ màu, và như vậy sẽ cho cảm giác mượt mà hơn nhiều

  • Hay đấy. Trên màn hình 1440p, tôi dùng kính lúp đeo đầu[1] và giảm tốc độ xuống 10 lần thì chơi được
    Nếu mật độ điểm ảnh cao hơn nữa thì có lẽ cần kính hiển vi thật
    [1] https://www.amazon.com/ProsKit-MA-016-Personal-Headband-Magn...

  • QBasic Nibbles cũng từng làm điều tương tự bằng các ký tự vẽ hộp ANSI
    Có ký tự văn bản chỉ dùng nửa “ô” theo chiều dọc, và bằng cách kết hợp khéo màu tiền cảnh/hậu cảnh, có thể tăng gấp đôi độ phân giải dọc trong chế độ văn bản

  • Nếu bạn cũng ngốc như tôi và thật sự định chơi, nên biết rằng giá trị Snake speed hoạt động ngược lại

    • Tốc độ là số mili giây mỗi khung hình
  • Có ai đủ già để nhớ niềm vui khi tinh chỉnh ClearType trên Windows XP không
    Đó là một cách lách rất hay để render chữ mượt hơn trên LCD độ phân giải thấp

    • Trên Windows 10 vẫn còn làm được. Chỉ là giờ không còn thú vị lắm nữa
  • Cách dễ nhất để nhìn thấy subpixel là đặt một giọt nước lên màn hình. Cách này có lẽ phóng đại khoảng 100 lần :)

  • Về phần phóng to/thu nhỏ để căn pixel CSS với pixel thật, tôi nghĩ chỉ cần dùng đơn vị như 0.25px là được chăng
    Hoặc trong JavaScript có thể chia cho window.devicePixelRatio để khớp động