2 điểm bởi GN⁺ 2026-01-18 | 1 bình luận | Chia sẻ qua WhatsApp
  • Phát triển kỹ thuật kết xuất ASCII bảo toàn đường viền và hình dạng của ảnh, giải quyết vấn đề rìa bị mờ của các phương pháp hiện có
  • Thay vì ánh xạ độ sáng đơn giản theo từng pixel, sử dụng cách tiếp cận dựa trên vector đa chiều để định lượng hình dạng trực quan (shape) của từng ký tự rồi đối sánh
  • Đo mật độ ở các vùng trên, dưới, trái, phải của từng ký tự để tạo shape vector mở rộng từ 2 chiều lên 6 chiều, qua đó hiện thực hóa việc chọn ký tự chính xác hơn
  • Áp dụng thuật toán tăng cường tương phản toàn cục và theo hướng (contrast enhancement) để làm rõ các đường biên
  • Thông qua tăng tốc GPU, bộ nhớ đệm và tìm kiếm bằng k-d tree, đạt hiệu năng kết xuất ASCII thời gian thực và hiện thực hóa hiệu ứng thị giác chất lượng cao

Chuyển đổi từ ảnh sang ASCII

  • ASCII có 95 ký tự có thể in được, và sử dụng phông chữ đơn cách (monospace) để chia ảnh thành lưới
    • Tính độ sáng của từng ô rồi ánh xạ theo mật độ của ký tự
  • Nội suy láng giềng gần nhất (nearest-neighbor interpolation) đơn giản gây ra hiện tượng jaggies với các đường biên răng cưa
  • Nếu lấy nhiều mẫu trong mỗi ô bằng siêu lấy mẫu (supersampling) để tính độ sáng trung bình thì sẽ mượt hơn, nhưng vẫn xuất hiện biên mờ
  • Cốt lõi của vấn đề là coi ký tự như pixel, tức là không xét đến hình dạng vốn có của ký tự

Tận dụng hình dạng ký tự (Shape)

  • Mỗi ký tự có phân bố mật độ thị giác khác nhau trong ô
    • Ví dụ: T nặng phần trên, còn L nặng phần dưới
  • Để định lượng điều này, đặt các vòng tròn lấy mẫu (circle) trong ô và tính tỷ lệ chiếm chỗ của ký tự ở từng vùng
  • Biểu diễn tỷ lệ chiếm chỗ của hai vùng trên và dưới thành vector để tạo shape vector 2 chiều
  • Tính trước shape vector của từng ký tự, sau đó chọn ký tự gần nhất với vector lấy mẫu của ảnh bằng khoảng cách Euclid (Euclidean distance)

Mở rộng sang vector hình dạng 6 chiều

  • Chỉ dùng 2 chiều trên và dưới thì khó biểu diễn các ký tự tập trung ở giữa hoặc lệch trái phải như -, p, q
  • Mở rộng ô thành 6 vòng tròn lấy mẫu để nắm bắt đầy đủ trên, giữa, dưới và khác biệt trái, phải
  • Shape vector 6 chiều phản ánh hình dạng ký tự chính xác hơn nhiều, đồng thời biểu diễn tốt cả ký tự tròn và chéo
  • Khi kết xuất cảnh 3D, đường viền ngoài sắc nét nhưng lại phát sinh vấn đề biên giữa các mặt bị mờ

Tăng cường tương phản (Contrast Enhancement)

  • Điều chỉnh từng phần tử của vector lấy mẫu bằng số mũ (exponent) để làm các giá trị tối tối hơn, trong khi giữ nguyên các giá trị sáng
    • Chuẩn hóa vector, áp dụng số mũ rồi khôi phục về phạm vi ban đầu
  • Qua quá trình này, khả năng phân biệt trực quan của đường biên được tăng cường, giúp việc chọn ký tự rõ ràng hơn
  • Ở các vùng có độ sáng đồng đều, thay đổi gần như không đáng kể nên vẫn giữ được chuyển sắc mượt
  • Tuy nhiên, ở một số biên có thể xuất hiện hiện tượng bậc thang (staircasing)

Tăng cường tương phản theo hướng (Directional Contrast Enhancement)

  • Bố trí thêm các vòng tròn lấy mẫu bên ngoài mỗi ô để thu thập thông tin độ sáng xung quanh
  • Các giá trị sáng trong vector lấy mẫu bên ngoài sẽ điều chỉnh phần tử tương ứng của vector bên trong theo hướng tối hơn, từ đó tăng cường tương phản theo hướng của đường biên
  • Khi mở rộng lấy mẫu bên ngoài để tăng ảnh hưởng giữa vùng trên, giữa và dưới, có thể biểu diễn đường biên mượt mà mà vẫn sắc nét
  • Khi kết hợp với tăng cường tương phản toàn cục, có thể hiện thực kết xuất ASCII cho cảnh 3D với đường biên rõ ràng và khả năng đọc cao

Tối ưu hiệu năng

  • Nếu chỉ lặp đơn giản việc tìm kiếm láng giềng gần nhất khi chọn ký tự thì sẽ chậm, vì vậy dùng k-d tree để tìm nhanh trong không gian đa chiều
  • Tái sử dụng kết quả của cùng một vector lấy mẫu thông qua bộ nhớ đệm
    • Lượng tử hóa từng vector theo đơn vị 5 bit để tạo khóa cache hiệu quả về bộ nhớ
    • Đặt phạm vi là 8 để cân bằng giữa chất lượng và mức sử dụng bộ nhớ
  • Việc tra cứu từ cache rất nhanh, nên ngay cả hàng nghìn ký tự cũng có thể xử lý theo thời gian thực
  • Việc tính toán vector lấy mẫu được chuyển sang GPU, để lấy mẫu bên trong và bên ngoài cùng các phép tăng cường tương phản được xử lý trong pipeline shader
    • Hiệu năng tăng nhiều lần so với CPU

Kết luận

  • Cách tiếp cận định lượng hình dạng ký tự bằng vector rồi khai thác chúng giúp cải thiện đáng kể độ phân giải và độ sắc nét của kết xuất ASCII
  • Phương pháp này có ý tưởng tương tự word embedding, nên có tiềm năng ứng dụng cho các bài toán thị giác khác
  • Triển khai ban đầu còn chậm, nhưng nhờ tăng tốc GPU, bộ nhớ đệm và tìm kiếm k-d tree, có thể đạt FPS mượt ngay cả trên thiết bị di động
  • Bài viết không đề cập đến biểu diễn ASCII dựa trên màu sắc, và có nhắc đến khả năng thử nghiệm thêm nhiều tổ hợp hình dạng và tương phản trong tương lai
  • Kết xuất ASCII không chỉ là một hiệu ứng thị giác đơn thuần, mà còn là ví dụ cho thấy tiềm năng mở rộng của nhận diện hình dạng và biểu diễn bằng vector

1 bình luận

 
GN⁺ 2026-01-18
Bình luận trên Hacker News
  • Nếu chuẩn hóa vector rồi tính khoảng cách Euclid, thì chỉ với phép nhân ma trận đơn giản (matmul) cũng có thể cho ra cùng kết quả
    Vì với các vector đã được chuẩn hóa, khoảng cách Euclid là một phép biến đổi tuyến tính của khoảng cách cosine
    Nếu điều quan trọng chỉ là thứ hạng (ranking) chứ không phải giá trị khoảng cách thực tế, thì có thể bỏ qua phép tính sqrt mà vẫn cho cùng kết quả, lại còn nhanh hơn một chút

    • Giá mà hồi những năm 90, lúc làm game engine, tôi đã biết điều này thì tốt biết mấy
  • Tôi rất thích kiểu bài viết như thế này. Trông có vẻ đơn giản bên ngoài, nhưng để làm cho nó thật hay thì cần đào sâu rất nhiều
    Cũng rất đáng đọc bài Lucas Pope viết khi phát triển hệ thống dithering cho Return of The Obra Dinn
    Nhật ký phát triển của Lucas Pope

  • Tôi giật mình khi đọc câu “đã tạo ảnh Sao Thổ bằng ChatGPT”
    Ảnh thật của Sao Thổ thì public domain đầy rẫy, nên tôi không hiểu vì sao lại phải tạo ảnh giả để làm ô nhiễm Internet

    • Nó làm tôi nhớ đến bài báo về tranh cãi ‘ảnh Mặt Trăng giả’ của Samsung. Biết đâu các hành tinh cũng không phải hàng thật?
    • Tôi không hiểu tại sao lại bắt nó tái tạo những hình ảnh vốn rất có thể đã nằm sẵn trong dữ liệu huấn luyện
    • “Tạo ảnh Sao Thổ bằng ChatGPT” mới chỉ là khởi đầu
      Một ngày nào đó, có lẽ chúng ta thậm chí sẽ không còn tự viết wiki, website hay forum nữa
      Nếu có thể lập tức tạo ra “một ảnh Sao Thổ tương phản cao kích thước X×Y”, thì đó sẽ là một thay đổi mang tính phép màu
      Cũng như máy tính bỏ túi hay Internet không giết chết sự sáng tạo, con người sẽ luôn chọn công cụ có ít ma sát nhất và tiếp tục hướng tới các vì sao
  • Mỗi lần xem ví dụ tôi đều nghĩ “ổn đấy, nhưng chắc vẫn cải thiện thêm được?”, và thật ấn tượng khi tác giả thực sự giải quyết luôn điều đó
    Đây là một bài viết rất đẹp, và cả blog cũng có độ sâu như vậy nên rất đáng theo dõi
    alexharri.com/blog

  • Khi làm dự án ascii-side-of-the-moon, tôi cũng từng cân nhắc tự triển khai một ASCII renderer
    Cuối cùng tôi dùng chafa, nhưng có lẽ một ngày nào đó tôi sẽ thử lại
    Tôi tò mò không biết có kế hoạch phát hành nó thành thư viện hay không, hoặc liệu có thể tham khảo mã nguồn website không

    • Tôi đã dùng công cụ ASCII Moon và thấy rất vui
      Hiện chưa có kế hoạch làm thư viện, nhưng nếu cần thì cứ tự nhiên lấy mã nguồn website dùng
      Nếu làm, có lẽ nên tăng khả năng tương thích bằng chuyển WebGL 2 → WebGL 1, và cũng sẽ cần một công cụ để tính trước shape vector theo từng font
  • Về câu “chưa từng thấy ví dụ nào dùng shape trong ASCII art”, thực ra đúng là có trình tạo dùng shape
    Đó là dự án ascii-silhouettify, dùng thuật toán chọn ký tự lớn nhất khớp với đường viền của vùng màu

    • Các ví dụ trong bộ sưu tập đơn sắc thực sự rất đẹp
    • Tuy nhiên có vẻ nó chậm hơn khoảng 150 lần. Có lẽ nếu tăng độ phân giải lấy mẫu thì cũng có thể đạt độ sắc nét tương tự
  • Acerola đã thử ASCII rendering dựa trên phát hiện cạnh vào năm 2024
    Cách làm là chồng các ký hiệu có hướng (| / - \) lên trên một pass dựa trên độ sáng
    Có thể tham khảo video liên quan

    • Có vẻ lĩnh vực này vẫn còn rất nhiều đất cho phong cách
      Ví dụ có thể thử nhiều hướng như dùng đường viền dày kiểu tranh 2D truyền thống, hoặc biểu đạt tương phản sáng-tối mềm như Chiaroscuro
  • Phần lớn các bộ lọc ASCII không xét đến hình dạng (shape) của glyph
    chafa xử lý từng glyph như bitmap 8×8, và tôi thấy cách tiếp cận này rất ấn tượng
    Nhìn vào mã nguồn chafagallery là có thể cảm nhận được độ tinh xảo đó

    • Tôi không thấy ví dụ render văn bản ASCII trong gallery của chafa, không biết có ví dụ nào như vậy không
    • Hồi đại học tôi cũng từng dùng cách chuyển bitmap 8×8 thành số nguyên 64-bit rồi so sánh bằng popcnt
      Tôi tò mò không biết cách tiếp cận tập trung vào tính định hướng có thể biểu diễn tốt hơn các hình dạng lớn hơn hay không
    • Cá nhân tôi thích nhất các glyph của IBM Code Page 437
      Nhìn vào oldschool PC fonts đúng là như rơi vào một hang thỏ không đáy
  • Tôi đang thử nghiệm đồ họa màu dựa trên chữ nổi Braille trong thời gian rảnh
    Độ phân giải thì đủ, nhưng độ chính xác trong biểu đạt màu sắc lại thiếu, nên sau khi lấy mẫu cần chỉnh tương phản (contrast fixup)
    Có lẽ sẽ hay nếu áp dụng kỹ thuật lấy mẫu của tác giả để tăng cường tương phản màu
    Trước đây tôi từng thử tăng tương phản bằng bộ lọc Sobel, nhưng thất bại vì nó không khớp hàng với lưới ký tự

  • Đây thực sự là một cách tiếp cận kỹ thuật xuất sắc cùng phần phân tích rất sâu
    Tôi đã hy vọng cuối bài sẽ được thấy phiên bản cải tiến của Cognition cube array, nhưng tiếc là không có
    Nó làm tôi nhớ tới một nhà thiết kế trên YouTube từng tạo favicon tốt hơn bằng tương phản màu subpixel
    Bài viết liên quan (Web Archive)

    • Tôi cũng muốn thấy phiên bản tăng tương phản của logo Cognition đó
      Dù vậy bản thân bài viết vẫn rất tuyệt, và các ví dụ động thực sự rất ấn tượng