- Mengembangkan teknik rendering ASCII yang mempertahankan kontur dan bentuk gambar, sehingga mengatasi masalah tepi buram pada metode konvensional
- Alih-alih pemetaan kecerahan sederhana per piksel, pendekatan ini menggunakan pendekatan berbasis vektor berdimensi tinggi yang mencocokkan bentuk visual (shape) setiap karakter setelah dikuantifikasi
- Dengan mengukur kepadatan area atas, bawah, kiri, dan kanan untuk tiap karakter, sistem membuat shape vector yang diperluas dari 2 dimensi menjadi 6 dimensi agar pemilihan karakter lebih presisi
- Untuk meningkatkan ketajaman garis batas, diterapkan algoritme peningkatan kontras global dan terarah (directional contrast enhancement)
- Melalui akselerasi GPU, caching, dan pencarian k-d tree, sistem berhasil mencapai performa rendering ASCII real-time dan menghadirkan efek visual berkualitas tinggi
Konversi dari Gambar ke ASCII
- ASCII memiliki 95 karakter yang dapat dicetak, dan gambar dibagi ke dalam grid menggunakan font monospace
- Kecerahan tiap sel dihitung lalu dipetakan berdasarkan kepadatan karakter
- Interpolasi nearest-neighbor yang sederhana menimbulkan artefak jaggies dengan tepi bergerigi
- Dengan supersampling, beberapa sampel diambil di dalam sel untuk menghitung rata-rata kecerahan sehingga hasil lebih halus, tetapi tepi tetap cenderung buram
- Inti masalahnya adalah memperlakukan karakter seperti piksel, tanpa mempertimbangkan bentuk khas tiap karakter
Memanfaatkan Bentuk Karakter
- Setiap karakter memiliki distribusi kepadatan visual yang berbeda di dalam sel
- Contoh:
T lebih berat di bagian atas, sedangkan L lebih berat di bagian bawah
- Untuk mengkuantifikasi hal ini, lingkaran sampling ditempatkan di dalam sel dan rasio area yang ditempati karakter pada tiap wilayah dihitung
- Rasio okupansi dua wilayah atas dan bawah dinyatakan sebagai vektor untuk membentuk shape vector 2 dimensi
- Shape vector setiap karakter dipra-hitung, lalu karakter terdekat dipilih dari vektor sampling gambar menggunakan Euclidean distance
Ekspansi ke Vektor Bentuk 6 Dimensi
- Dua dimensi atas-bawah saja sulit merepresentasikan karakter yang berpusat di tengah atau kiri-kanan seperti
-, p, dan q
- Sel diperluas menjadi 6 lingkaran sampling untuk menangkap perbedaan atas-tengah-bawah serta kiri-kanan
- Shape vector 6 dimensi merepresentasikan bentuk karakter dengan jauh lebih presisi, dan juga mampu menggambarkan karakter melingkar dan diagonal dengan baik
- Saat merender adegan 3D, garis luar tampak tajam, tetapi muncul masalah berupa batas antarpermukaan yang buram
Peningkatan Kontras
- Setiap elemen pada vektor sampling disesuaikan menggunakan eksponen, sehingga nilai gelap menjadi lebih gelap sementara nilai terang tetap dipertahankan
- Vektor dinormalisasi, diberi eksponen, lalu dikembalikan ke rentang semula
- Proses ini memperkuat pemisahan visual pada garis batas, sehingga pemilihan karakter menjadi lebih jelas
- Pada area dengan kecerahan seragam, perubahan hampir tidak terlihat sehingga gradasi halus tetap terjaga
- Namun, pada sebagian batas muncul artefak staircasing
Peningkatan Kontras Terarah
- Lingkaran sampling eksternal juga ditempatkan di luar tiap sel untuk mengumpulkan informasi kecerahan di sekitarnya
- Nilai terang pada vektor sampling eksternal menggelapkan elemen yang bersesuaian pada vektor internal, sehingga kontras pada arah batas diperkuat
- Dengan memperluas sampling eksternal agar pengaruhnya mencakup area atas, tengah, dan bawah, dimungkinkan representasi batas yang halus namun tajam
- Jika digabungkan dengan peningkatan kontras global, hasilnya adalah rendering ASCII untuk adegan 3D yang memiliki batas tegas dan keterbacaan tinggi
Optimasi Performa
- Karena pengulangan sederhana untuk pencarian tetangga terdekat saat memilih karakter lambat, digunakan k-d tree untuk pencarian cepat di ruang multidimensi
- Hasil dari vektor sampling yang sama digunakan kembali melalui caching
- Setiap vektor dikuantisasi per 5 bit untuk membuat cache key yang efisien secara memori
- Rentang diatur ke 8 demi menyeimbangkan kualitas dan penggunaan memori
- Pencarian yang sudah tercache berlangsung sangat cepat, sehingga ribuan karakter pun dapat diproses secara real-time
- Perhitungan vektor sampling dipindahkan ke GPU, sehingga sampling internal-eksternal dan operasi peningkatan kontras diproses dalam pipeline shader
- Kinerja meningkat beberapa kali lipat dibanding CPU
Kesimpulan
- Pendekatan yang memanfaatkan bentuk karakter sebagai vektor terkuantifikasi secara signifikan meningkatkan resolusi dan ketajaman rendering ASCII
- Pendekatan ini memiliki konsep yang mirip dengan word embedding, dan berpotensi diterapkan pada masalah visual lain
- Implementasi awalnya lambat, tetapi dengan akselerasi GPU, caching, dan pencarian k-d tree, performa FPS yang mulus dapat dicapai bahkan di perangkat mobile
- Representasi ASCII berbasis warna tidak dibahas, tetapi disebutkan adanya peluang eksperimen lebih lanjut dengan kombinasi bentuk dan kontras yang lebih beragam
- Rendering ASCII bukan sekadar efek visual sederhana, melainkan contoh yang menunjukkan potensi perluasan pengenalan bentuk dan representasi vektor
1 komentar
Komentar Hacker News
Jika vektor dinormalisasi lalu dihitung jarak Euclidean, hasil yang sama bisa diperoleh hanya dengan perkalian matriks sederhana (matmul)
Karena pada vektor yang dinormalisasi, jarak Euclidean adalah transformasi linear dari jarak kosinus
Jika yang penting hanya peringkat (ranking) dan bukan nilai jarak sebenarnya, operasi sqrt juga bisa dihilangkan dengan hasil yang sama, dan perhitungannya sedikit lebih cepat
Saya sangat suka tulisan seperti ini. Sekilas terlihat sederhana, tetapi untuk membuatnya benar-benar bagus perlu eksplorasi yang mendalam
Saya juga merekomendasikan tulisan Lucas Pope saat mengembangkan sistem dithering untuk Return of The Obra Dinn
Catatan pengembangan Lucas Pope
Saya kaget saat membaca kalimat “gambar Saturnus dibuat dengan ChatGPT”
Foto Saturnus asli sudah bertebaran di domain publik, jadi saya heran kenapa harus membuat gambar palsu dan mencemari internet
Suatu hari nanti, mungkin kita bahkan tidak akan lagi menulis wiki, situs web, atau forum secara langsung
Jika gambar Saturnus berkontras tinggi berukuran X×Y bisa dibuat seketika, itu akan menjadi perubahan yang terasa seperti sihir
Seperti kalkulator dan internet yang tidak mematikan kreativitas, manusia akan selalu memilih alat dengan gesekan paling kecil dan terus melangkah menuju bintang-bintang
Setiap kali melihat contohnya, saya selalu berpikir, “Bagus sih, tapi rasanya masih bisa ditingkatkan lagi?” lalu kagum karena penulis benar-benar menyelesaikan itu
Tulisannya sangat indah, dan seluruh blognya punya kedalaman seperti ini sehingga layak diikuti
alexharri.com/blog
Saat membuat proyek ascii-side-of-the-moon, saya sempat mempertimbangkan untuk mengimplementasikan sendiri ASCII renderer
Pada akhirnya saya memakai chafa, tetapi suatu saat ingin mencobanya lagi
Saya penasaran apakah ada rencana merilis ini sebagai library, atau bolehkah saya menjadikan kode situs web sebagai referensi
Saat ini belum ada rencana menjadikannya library, tetapi kalau perlu, silakan ambil kode situs webnya dengan bebas
Kalau saya membuatnya, saya rasa perlu meningkatkan kompatibilitas lewat konversi WebGL 2 → WebGL 1, dan juga alat untuk menghitung shape vector lebih dulu untuk tiap font
Terkait pernyataan “Saya belum pernah melihat contoh ASCII art yang memanfaatkan shape”, sebenarnya ada generator yang memang menggunakan shape
Proyek itu bernama ascii-silhouettify, dan memakai algoritme yang memilih karakter terbesar agar sesuai dengan kontur area warna
Acerola mencoba ASCII rendering berbasis deteksi tepi pada 2024
Metodenya adalah menumpuk simbol berarah (| / - \) di atas pass berbasis kecerahan
Lihat video terkait
Misalnya, memakai garis batas tebal seperti seni 2D tradisional, atau mencoba berbagai pendekatan untuk mengekspresikan kontras terang-gelap yang lembut seperti Chiaroscuro
Kebanyakan filter ASCII tidak mempertimbangkan bentuk (shape) glif
chafa memperlakukan tiap glif sebagai bitmap 8×8, dan pendekatan itu menurut saya sangat mengesankan
Dari source chafa dan galerinya, terasa sekali tingkat ketelitiannya
Saya penasaran apakah pendekatan yang berpusat pada arah bisa lebih baik dalam merepresentasikan bentuk yang lebih besar
Melihat oldschool PC fonts benar-benar seperti masuk ke lubang kelinci tanpa akhir
Di waktu senggang saya sedang bereksperimen dengan grafik berwarna berbasis huruf Braille
Resolusinya sudah memadai, tetapi presisi representasi warnanya kurang, jadi setelah sampling perlu penyesuaian kontras (contrast fixup)
Sepertinya menarik untuk mencoba menerapkan teknik sampling penulis ke penguatan kontras warna
Sebelumnya saya sempat mencoba meningkatkan kontras dengan filter Sobel, tetapi gagal karena tidak sejajar dengan kisi karakter
Ini benar-benar pendekatan teknis yang luar biasa dan analisis yang mendalam
Di bagian akhir saya sempat berharap bisa melihat versi yang diperbaiki dari Cognition cube array, tetapi ternyata tidak ada, jadi agak disayangkan
Ini mengingatkan saya pada seorang desainer di YouTube yang dulu membuat favicon lebih baik dengan kontras warna subpiksel
Tulisan terkait (Web Archive)
Meski begitu, artikelnya sendiri tetap luar biasa, dan contoh-contoh dinamisnya benar-benar mengesankan