3 poin oleh GN⁺ 2024-01-25 | 1 komentar | Bagikan ke WhatsApp
  • Tim Ctrl-Alt-Test memulai eksperimen pada November 2022 untuk memuat demo real-time yang tampak seperti film animasi pendek ke dalam 8kB, lalu merilis The Sheep and the Flower pada April 2023
  • Hasilnya adalah satu file .exe yang menghasilkan grafis dan musik tanpa file resource atau dependensi eksternal, sementara adegan dihitung secara real-time di GPU dengan shader GLSL dan raymarching
  • Domba, rambu, kamera, dan timeline tidak dibuat dari model atau tekstur yang disimpan, melainkan dari SDF, tekstur 3D prosedural, dan parameter waktu yang di-hardcode, dengan sekitar 25 shot kamera yang disetel manual
  • Musik dibuat dengan OpenMPT dan 4klang, sambil mengurangi jumlah instrumen dari 16 menjadi 13 dan menambah pengulangan untuk meningkatkan efisiensi kompresi
  • Ukuran akhir 8kB dimungkinkan berkat kompresi Crinkler dan peningkatan Shader Minifier; kode shader 42kB masuk ke sekitar 5kB setelah minimisasi dan kompresi, menyisakan ruang untuk musik dan kode C++

Satu file executable dalam 8kB

  • The Sheep and the Flower adalah animasi real-time dalam bentuk file executable Windows yang dirilis pada April 2023
  • Satu file .exe menghasilkan semuanya, tanpa file resource terpisah atau dependensi eksternal
    • Untuk menjalankannya dibutuhkan Windows dan driver terbaru
  • Tujuannya adalah memasukkan grafis, animasi, penyutradaraan, pergerakan kamera, dan musik ke dalam 8kB
  • Kode sumber dipublikasikan di GitHub: ctrl-alt-test/mouton

Alat yang dipakai untuk grafis, musik, dan kompresi

  • Semua elemen visual dihitung secara real-time di GPU
    • Shader GLSL mencakup informasi timeline, pengaturan kamera, hingga representasi adegan
    • Rendering dilakukan dengan raymarching
  • Shader diperkecil dengan Shader Minifier
  • Musik dibuat dengan OpenMPT dan synthesizer 4klang
    • Instrumen dideskripsikan secara prosedural
    • Daftar not dikompresi
  • Kode ditulis dalam C++ di Visual Studio 2022
  • Flag compiler dan inisialisasi dimulai dari framework Leviathan
  • File executable akhir dikompresi dengan Crinkler

Mengapa 8kB

  • Di demoscene, kategori dengan batas ukuran seperti 4kB dan 64kB sudah umum
  • Karya sebelumnya terutama menargetkan 64kB, tetapi 8kB memberi batasan dan aturan yang sepenuhnya berbeda
  • Teknik intro 4kB menarik, tetapi dianggap terlalu terbatas untuk storytelling yang layak
  • Demoparty Revision menambahkan kategori kompetisi 8kB beberapa tahun lalu, dan itu dijadikan kesempatan bagus untuk bereksperimen

Dunia yang digambar dengan dua segitiga

  • Seperti pendekatan yang menjadi standar di demoscene sejak 2008, sebuah persegi panjang yang menutupi seluruh layar digambar dengan dua segitiga
  • Di atas persegi panjang ini, shader GLSL menghitung warna tiap piksel dan tiap frame
  • Fungsi shader menerima koordinat dan waktu sebagai input lalu mengembalikan warna
  • Tantangan utamanya adalah bagaimana merepresentasikan domba dan seluruh adegan di dalam fungsi itu

Menyusun adegan dengan SDF

  • Signed Distance Field (SDF) adalah fungsi yang menghitung jarak dari satu titik di ruang ke objek terdekat
    • Di permukaan, nilainya 0
    • Di dalam objek, nilainya negatif
  • Bentuk dasar seperti bola atau kotak bisa direpresentasikan dengan rumus sederhana
  • Beberapa distance field digabungkan untuk membentuk adegan
    • Gabungan dua objek bisa dibuat dengan nilai minimum jaraknya
    • Irisan bisa dibuat dengan nilai maksimumnya
    • Smooth union memungkinkan bentuk yang lebih organik
  • Domba dibuat dengan merakit dan menggabungkan bentuk sederhana seperti kerucut dan bola, sementara badan dan bulunya dibentuk dengan fungsi noise 3D

Cara raymarching menentukan piksel

  • Raymarching adalah teknik rendering yang menggunakan SDF untuk memajukan sinar sedikit demi sedikit di dalam adegan 3D
  • Berbeda dari ray tracing tradisional, titik perpotongan tidak dihitung langsung secara matematis
  • SDF memberi tahu seberapa jauh sinar bisa bergerak tanpa bertabrakan, lalu proses itu diulang
  • Saat jaraknya menjadi 0 atau mendekati 0, titik perpotongan dianggap telah ditemukan
  • Ketika ada titik perpotongan, bisa ditentukan apakah piksel saat ini milik domba, langit, atau objek lain
  • Pencahayaan membutuhkan normal permukaan, yang diperkirakan dengan menghitung gradien di sekitar titik tersebut
  • Bayangan dihitung dengan mengirim sinar lain dari titik perpotongan ke arah matahari untuk memeriksa apakah ada objek di tengahnya

Menyampaikan cerita dengan daya ekspresi yang kecil

  • Demo ini tidak memiliki suara atau teks, dan karakternya hanya satu
  • Domba hanya bisa berjalan, menggerakkan kepala dan mata, dan bahkan tidak bisa berputar
  • Untuk menyampaikan emosi dalam keterbatasan ini, elemen yang tidak terkait cerita disingkirkan
    • Awalnya mereka membayangkan gurun, bukit pasir, dan langit, tetapi menilai itu tidak diperlukan untuk cerita
    • Latar belakang dipertahankan putih polos
    • Tekstur dikurangi kecuali pada rambu dan mata yang membawa makna
  • Dengan menjaga cakupan tetap kecil, mereka bisa fokus pada detail, polishing, camera work, editing, dan sinkronisasi musik
  • Tiap shot disusun manual, dan animasinya disetel berulang kali agar alurnya terasa alami

Kamera dan penyutradaraan

  • Kamera dipakai sebagai alat untuk menyampaikan cerita
  • Shot lebar digunakan saat domba mengembara lama untuk menciptakan rasa kesepian
  • Extreme close-up pada mata dipakai saat domba menyadari rambu itu
  • Ketika domba menatap rambu, kamera melakukan zoom-in perlahan ke arah kepala untuk meningkatkan fokus
  • Kegembiraan domba disampaikan dengan menumpuk beberapa ekspresi
    • Efek 2D bergaya kartun
    • Langkah yang dipercepat
    • Gerakan ekor yang ditegaskan
    • Goyangan kepala yang dilebih-lebihkan
    • Perubahan dramatis pada musik

Cara pengembangan untuk iterasi cepat

  • Kode sumber berisi banyak konstanta yang di-hardcode
    • Ukuran mata domba
    • Kecepatan pergerakan kamera
    • Durasi tiap shot
    • Nilai seperti warna bunga disetel berulang kali
  • Demi umpan balik cepat, shader dikompilasi ulang saat runtime sehingga grafis bisa diperbarui dalam waktu kurang dari 1 detik
  • Sebuah player diperlukan untuk menyesuaikan animasi dan kamera
    • Pause
    • Play
    • Kontrol waktu
    • Langsung memeriksa hasil setelah live reload shader
  • Dukungan musik juga wajib agar musik dan animasi bisa sinkron dengan akurat
  • Prototipe awal dibuat di Shadertoy, lalu dipindahkan melalui KodeLife ke proyek C++

Musik yang dibuat dengan 4klang

  • Musik adalah elemen penting untuk menyampaikan cerita, dan dibutuhkan beberapa suasana serta transisi pada momen tertentu
  • Alat yang dipakai di intro 4kB tetap digunakan, tetapi diberi lebih banyak ruang untuk komposisi yang lebih kompleks
  • 4klang synthesizer menyediakan plugin yang bisa dipakai di software musik, lalu mengekspor file assembly
  • File assembly ini dikompilasi dan di-link bersama demo
  • Saat demo berjalan, synth secara prosedural menghasilkan suara waveform di thread terpisah lalu mengirimkannya ke sound card
  • Musik pertama yang dibuat ternyata lebih besar dari perkiraan, sehingga dilakukan berbagai penyesuaian untuk mengecilkannya
    • Jumlah instrumen dikurangi dari 16 menjadi 13
    • Tema ending dikomposisi ulang agar sesuai dengan tempo keseluruhan musik
    • Pengulangan ditambah agar lebih mudah dikompresi
    • Perubahan yang hampir tak terdengar, seperti panjang not pada suara latar, dipakai untuk meningkatkan rasio kompresi
  • Struktur keseluruhan musik dipertahankan sambil meminimalkan penurunan kualitas dan menghemat ruang

Animasi dan sinkronisasi waktu

  • Demo ini mengevaluasi ulang semuanya di setiap frame tanpa pra-perhitungan atau cache
  • Ini buruk untuk performa, tetapi menguntungkan untuk animasi karena elemen apa pun bisa berubah berdasarkan waktu
  • Keseluruhan demo terdiri dari sekitar 25 shot kamera yang disusun manual
  • Tiap shot mendeskripsikan bagaimana 18 parameter berubah seiring waktu
    • Posisi tiap objek
    • Status domba
    • Posisi kamera
    • Fokus
    • Target yang dilihat kamera
  • Sebagai contoh, camPos = vec3(22., 2., time*0.6-10.); saja sudah cukup untuk merepresentasikan gerakan linear kamera dalam satu shot
  • time bukan berarti waktu absolut sejak demo dimulai, melainkan waktu sejak shot itu dimulai
    • Ini mengurangi dampak pada sisa demo ketika shot disisipkan, dihapus, atau diubah
  • Interpolasi linear sederhana bisa terlihat mekanis, sehingga dalam banyak kasus digunakan smoothstep
  • Kode timeline berada di dalam vertex shader
  • Definisi shot memang berisi banyak kode berulang, tetapi pengulangan justru menguntungkan untuk kompresi

Tekstur dan material

  • Dalam renderer tradisional, tekstur 2D ditempelkan ke permukaan model 3D
  • Dalam pendekatan raymarching, koordinat tekstur sulit dihitung dengan mudah, sehingga tekstur 3D dihitung saat itu juga
  • Ketika raymarcher menemukan posisi 3D yang akan dirender, koordinat 3D itu diteruskan ke fungsi tekstur
  • Rambu lalu lintas dibuat secara matematis dengan membentuk bingkai segitiga atau persegi panjang, lalu isi di dalamnya digambar dengan kombinasi beberapa fungsi
    • Simbol restoran terdiri dari empat bentuk oval hitam dan dua bentuk putih yang membentuk lekukan
  • Untuk variasi visual, bukan hanya tekstur yang dibedakan, tetapi juga materialnya
    • Misalnya, kuku domba diberi pantulan berbeda dengan memanfaatkan koefisien Fresnel

Pantulan palsu untuk menghidupkan mata

  • Selama pengembangan, mata lama terlihat datar dan tidak hidup
  • Mata merupakan elemen penting dalam desain karakter dan penyampaian cerita
  • Dari gambar referensi karakter kartun, mereka melihat bahwa iris sering ada tetapi tidak wajib, sedangkan pupil hampir selalu digambar besar
  • Untuk membuat mata tampak berkilau, diperlukan pantulan cahaya di dalam mata
  • Dengan persamaan pencahayaan yang ada, pantulan hanya muncul ketika matahari dan kamera berada di posisi tertentu
  • Untuk mengatasinya, vektor normal permukaan dimodifikasi agar peluang munculnya pantulan matahari lebih tinggi
  • Selain itu, environment mapping juga digunakan
    • Dalam game, teknik ini biasanya dipakai untuk menyederhanakan pantulan lingkungan nyata demi optimasi
    • Di sini, dunia sebenarnya nyaris sepenuhnya putih, tetapi tekstur dipakai untuk menambahkan detail palsu
  • Bagian putih mata dan pupil diberi pantulan yang jauh lebih kompleks daripada dunia kosong di sekitarnya
    • Beberapa sumber cahaya palsu
    • Gradien yang meniru tanah gelap dan langit biru

Post-processing dan gaya visual

  • Nuansa akhir dan kualitas gambar dipoles lewat post-processing
  • Post-processing yang digunakan adalah sebagai berikut
    • Color grading
    • Koreksi gamma
    • Vignette ringan
    • Filter FXAA 2-pass untuk mengurangi aliasing
  • Beberapa efek seperti efek bintang di mata atau efek layar ending juga diimplementasikan pada tahap post-processing
    • Efek-efek ini murni 2D dan tidak ada di dunia 3D
  • Mereka sempat bereksperimen dengan gaya kartun lama
    • Deteksi outline agar terlihat seperti gambar tangan
    • Rendering hitam-putih
    • Grain dan noise
  • Setelah diskusi, eksperimen ini ditinggalkan dan fokus dialihkan ke tampilan yang lebih bersih dan modern

Kompresi Crinkler

  • Ide intinya adalah bukan menyimpan data, melainkan menyimpan kode yang menghasilkan data itu
  • Musik menyimpan daftar not yang harus dimainkan dan daftar instruksi untuk tiap instrumen
  • Crinkler adalah alat kompresi yang dirancang untuk demoscene dan intro 1kB~8kB
  • Karena file executable harus bisa mengekstrak dirinya sendiri, Crinkler menyertakan sedikit kode assembly yang dapat membuka sisa file executable
  • Crinkler memprioritaskan optimasi ukuran
    • Algoritme kompresinya memakan waktu
    • Proses dekompresinya relatif lambat
    • Menggunakan ratusan MB RAM
  • Namun Crinkler saja tidak cukup, dan diperlukan minimisasi tambahan agar kode sumber shader 42kB bisa dimasukkan ke dalam file executable

Peningkatan Shader Minifier

  • Karena kode sumber shader dimasukkan ke dalam biner akhir, ukurannya harus dibuat sekecil mungkin
  • Minimisasi manual memang mungkin, tetapi akan menimbulkan masalah pemeliharaan dan iterasi cepat
  • Shader Minifier adalah alat minimisasi shader yang dikembangkan sejak 2011
  • Alat ini menghapus spasi dan komentar, memendekkan nama variabel, serta melakukan lebih banyak transformasi
  • Intro 8kB memuat jauh lebih banyak kode daripada 4kB, sehingga muncul masalah baru, dan pekerjaan demo sempat dihentikan selama sebulan untuk menambahkan fitur yang dibutuhkan
  • Untuk minimisasi yang baik, yang dibutuhkan bukan sekadar minifier sederhana, tetapi source-to-source compiler mirip Closure Compiler
  • Transformasi yang dilakukan Shader Minifier meliputi
    • Mengganti nama variabel dan fungsi
    • Inlining variabel
    • Evaluasi ekspresi aritmetika konstan
    • Inlining fungsi
    • Menghapus dead code
    • Menggabungkan deklarasi
  • Mengurangi ukuran kode saja tidak cukup; output juga harus ramah kompresi
    • Beberapa transformasi memang mengecilkan kode, tetapi justru bisa memperbesar ukuran setelah dikompresi
    • Selama pengembangan demo yang berulang, ukuran setelah kompresi harus terus dicek
  • Peningkatan baru pada Shader Minifier menghemat sekitar 600 byte dalam biner terkompresi
  • Pada akhirnya, kode shader 42kB masuk ke sekitar 5kB setelah diminimalkan dan dikompresi
    • Ruang sisanya dipakai untuk musik dan kode C++

Hasil yang dibangun di atas karya orang lain

  • Demo ini dibuat di atas karya orang lain seperti teknik raymarching, software pembuat musik, dan algoritme kompresi
  • Mereka berharap fitur baru yang ditambahkan ke Shader Minifier akan membantu membuat demo yang lebih baik di masa depan
  • Kategori 8kB menawarkan lebih banyak kemungkinan dibanding 4kB, dan ada harapan agar kategori ini menjadi lebih populer
  • Sebagai perbandingan, teks aslinya sendiri berukuran sekitar 21.000 karakter, yang berarti akan membutuhkan 21kB jika disimpan apa adanya

1 komentar

 
GN⁺ 2024-01-25
Opini Hacker News
  • Saya pembuat film asli yang menjadi inspirasi film ini: https://www.youtube.com/watch?v=khWXdkryBE4
    Versi aslinya saja, hanya file Blender, SVG, dan audio, sudah berukuran MB, jadi sangat mengesankan bahwa remake-nya bisa muat dalam 8kB
    Senang melihat lisensi Creative Commons ternyata benar-benar berguna, hanya saja akan lebih bagus kalau mereka memakai karakter landak dan melodi audio yang sama

  • Sloot hidup kembali!!!
    https://en.m.wikipedia.org/wiki/Sloot_Digital_Coding_System

    • Sloot mungkin tidak berhasil, tetapi algoritma kompresi di bawah ini cukup efektif untuk memasukkan seluruh film ke dalam beberapa kB
      Kumpulkan banyak demoscener, tunjukkan filmnya, lalu kurung mereka beberapa waktu di ruangan yang ada komputernya
      Ini bekerja lebih baik kalau ada layar besar, sistem suara besar, bir, dan junk food; setelah itu tinggal ambil file executable hasilnya
    • Itu belum ada apa-apanya. Saya perkenalkan program 1 byte yang mencetak seluruh karya Shakespeare:
      a
      Interpreter yang ditulis dengan Rust demi performa akan mengevaluasi perintah a dan mencetak payload tertentu yang disertakan saat runtime ke STDOUT
    • “Pada 1999, beberapa hari sebelum kontrak penjualan penemuannya ditandatangani, Sloot tiba-tiba meninggal karena serangan jantung. Kode sumbernya tidak pernah ditemukan, dan teknologi serta klaim tersebut tidak pernah direproduksi atau diverifikasi”
      Benar-benar nasib sial yang kejam bagi semua orang
    • Tafsiran cepat saya setelah membaca sekilas artikelnya: kemungkinan ia menjelaskan algoritma hash secara keliru kepada orang-orang nonteknis
      Mereka mungkin tidak memahami bahwa a) itu fungsi satu arah dan b) sekalipun bukan satu arah, banyak input bisa dipetakan ke hash yang sama
  • Video demoscene cukup menarik, tetapi sangat kurang dikenal
    https://www.youtube.com/playlist?list=PLRQwR4-_0PR9HBI_GZs1nTn7q5LTkGeCN
    Akan bagus kalau ada kanal yang menguraikan bagian dalamnya dengan visual yang bagus, seperti retro game mechanics

    • Menonton demo sebagai video YouTube terasa agak curang, tetapi dibanding 20 tahun lalu saya sekarang lebih berhati-hati mengunduh dan menjalankan executable acak, jadi saya bersyukur ada videonya
      Pada masa belum ada video, kita harus menunggu cukup lama proses dekompresi dan pemrosesan sebelum akhirnya bisa terkesan atau kecewa
      Dulu saya sering menonton demo saat istirahat, dan itu menjadi latar yang sempurna untuk kondisi mental saya waktu itu
    • Sepertinya ini kesempatan untuk membagikan demo favorit saya sepanjang masa. Intrinsic Gravity dari Still: https://youtu.be/-ZxPhDC-r3w
    • Setuju. Akan luar biasa kalau bisa melihat struktur internal sesuatu seperti .kkrieger
      https://en.wikipedia.org/wiki/.kkrieger
    • Jika AGI sudah terpecahkan, saya ingin melihat demoscene untuk kecerdasan. Seberapa jauh itu bisa dikompresi?
      Lebih jauh lagi, seberapa kecil kita bisa membuat dunia yang terdiri dari agen-agen yang saling cerdas?
      Tambahan: untuk yang memberi downvote, kalian tidak bermimpi? Di depan ada banyak hal yang benar-benar gila dan fantastis menanti
    • Ini mengingatkan saya pada shader wars
  • Saya tahu teknologi di baliknya cukup berbeda, tetapi ini mengingatkan saya pada .kkrieger dulu. Seluruh 3D FPS dikompresi menjadi 96k, dan itu benar-benar keren
    https://en.m.wikipedia.org/wiki/.kkrieger

  • Setelah banyak menonton demoscene dan membaca cara pembuatannya, kita mulai memahami batasannya, dan menjadi jelas bahwa unsur seperti domba, terutama penampang kerucut pada kakinya, bisa diekspresikan dengan persamaan yang sangat terkompresi dan dianimasikan dengan cara serupa
    Namun setahu saya kebanyakan demo mengandalkan GPU dan kemampuan akselerasi 3D yang kuat, sedangkan demo 2D bergaya anime Jepang tampaknya jarang atau hampir tidak ada dalam ukuran kecil
    Apakah animasi 3D memang lebih mudah dalam praktiknya?
    Sebagai tambahan, “mouton” berarti “domba” dalam bahasa Prancis, dan dari situlah “mutton” berasal

    • Cara yang Anda jelaskan sendiri tampaknya menunjukkan mengapa 3D umum di demo. Bentuk geometris 3D dapat diekspresikan sebagai persamaan bentuk tertutup yang hanya membutuhkan ruang penyimpanan minimal
      Sebaliknya, cara ‘matematis’ untuk menyimpan animasi bergaya 2D kurang lebih hanya menyimpan kontur sebagai kurva SVG, lalu memakai algoritma pengisian ruang untuk pewarnaan area
      Dengan perhitungan kasar saja, satu busur kurva atau satu garis bisa memakan ruang penyimpanan sebanyak deskripsi seluruh volume geometri, dan untuk menyimpan animasi kurva-kurva itu dibutuhkan jauh lebih banyak ruang dibanding matriks transformasi kecil untuk volume 3D
      Kompleksitas algoritma rendering juga tampaknya akan meningkat, baik dalam kompleksitas algoritme aktual maupun kompleksitas ruang
      Catatan: menyimpan banyak bitmap lalu memutarnya seperti flipbook pun bisa diklaim ‘matematis’ jika memakai algoritma dekompresi prosedural yang menghasilkan frame penuh dari delta
      Namun saya tidak melihat pendekatan seperti itu ada, dan kebutuhan ruangnya akan sangat besar dibanding deskripsi volume 3D
    • Sebagian besar animasi 2D pun pada akhirnya menggambarkan peristiwa di ruang 3D, jadi secara umum akan jauh lebih mudah menggambarkan peristiwa 3D secara langsung
  • Ini sedikit lebih besar dari 8kB, tetapi jika Anda suka animasi tentang domba yang secara tak terduga gelap, saya merekomendasikan open movie Cosmos Laundromat dari Blender Foundation
    Film-film yayasan ini selalu terasa anehnya gelap untuk ukuran demo teknologi, dan menurut saya karya ini khususnya sangat berhasil
    [0] https://www.youtube.com/watch?v=Y-rmzh0PI3c

  • Sebagai peringatan dulu, filmnya berakhir dengan “to be continued”, dan halaman Wikipedia menuliskan seperti ini:
    “Film ini awalnya dimaksudkan sebagai titik awal untuk sebuah film panjang. Sekuel pendeknya sudah memiliki naskah dan desain, tetapi tidak pernah masuk produksi. Pada 2020, [pembuatnya] mengumumkan bahwa satu film ini akan menjadi keseluruhan proyek tersebut”
    Kalau tidak ingin kecewa karena tidak akan pernah melihat akhir dari konsep yang menarik ini, mungkin lebih baik dilewati

    • Terkait itu, sebagai tambahan pribadi, berkat Netflix seluruh filmnya tersedia untuk diunduh dari S3 sebagai rangkaian 18.192 gambar EXR tak terkompresi
      Ini berguna saat bereksperimen dengan HDR di DaVinci Resolve
      [1] https://opencontent.netflix.com/#h.uyzoa2bivz2j
    • Ungkapan “gelap secara aneh” sepertinya cukup baik menjelaskan selera humor Belanda, dan kemungkinan besar itulah alasan utamanya
  • 8KB adalah salah satu kategori di demoscene. Di Pouet ada indeks yang merapikan karya-karya seperti ini dengan baik
    0. https://www.pouet.net/prodlist.php?type%5B%5D=8k&page=1

  • Razor 1911. Nostalgia murni

    • Grup yang paling dikenal karena warez dan cracking, serta ASCII art di file FILE_ID.DIZ dan .nfo
      Banyak kenangan indah dari puluhan tahun lalu muncul kembali :-)
    • Senang melihat mereka masih membuat seni keren di suatu tempat
  • Benar-benar menakjubkan, dan saya suka bagaimana dalam kondisi penuh batasan pun ceritanya bisa selucu dan sekreatif ini. Sungguh mengesankan
    Ingin mendengar lebih banyak detail teknis tentang trik dan penghematan seperti apa yang mereka lakukan untuk memangkas byte

  • Lucu sekaligus benar-benar mencengangkan. Akhirnya saya menonton film yang ending-nya tidak bisa saya tebak