3 คะแนน โดย GN⁺ 2024-01-25 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ทีม Ctrl-Alt-Test เริ่มทดลองตั้งแต่เดือนพฤศจิกายน 2022 เพื่อนำ เดโมแบบเรียลไทม์ที่ดูเหมือนแอนิเมชันขนาดสั้น มาใส่ไว้ภายใน 8kB และเปิดตัว The Sheep and the Flower ในเดือนเมษายน 2023
  • ผลลัพธ์คือไฟล์ .exe เดี่ยวที่สร้างกราฟิกและเพลงขึ้นมาเอง โดยไม่มีไฟล์ทรัพยากรหรือ dependency ภายนอก และฉากต่างๆ ถูกคำนวณแบบเรียลไทม์บน GPU ด้วย GLSL shader และ raymarching
  • แกะ ป้าย กล้อง และ timeline ไม่ได้ประกอบจากโมเดลหรือ texture ที่บันทึกไว้ แต่สร้างจาก SDF, texture 3D แบบ procedural และพารามิเตอร์เวลาที่ hardcode ไว้ โดยมีช็อตกล้องประมาณ 25 ช็อตที่ปรับแต่งด้วยมือ
  • เพลงสร้างด้วย OpenMPT และ 4klang โดยลดจำนวนเครื่องดนตรีจาก 16 ชิ้นเหลือ 13 ชิ้น และเพิ่มการซ้ำเพื่อเพิ่มประสิทธิภาพการบีบอัด
  • ขนาดสุดท้าย 8kB เป็นไปได้ด้วย การบีบอัด Crinkler และการปรับปรุง Shader Minifier โดยโค้ด shader ขนาด 42kB หลังย่อและบีบอัดแล้วเหลือประมาณ 5kB ทำให้ยังมีพื้นที่สำหรับเพลงและโค้ด C++

ไฟล์ executable เดี่ยวที่บรรจุอยู่ใน 8kB

  • The Sheep and the Flower คือแอนิเมชันแบบเรียลไทม์ในรูปแบบไฟล์ executable บน Windows ที่เปิดตัวในเดือนเมษายน 2023
  • ไฟล์ .exe เพียงไฟล์เดียวสร้างทุกอย่างขึ้นมาเอง โดยไม่มีไฟล์ทรัพยากรแยกหรือ dependency ภายนอก
    • การรันต้องใช้ Windows และไดรเวอร์รุ่นใหม่
  • เป้าหมายคือใส่กราฟิก แอนิเมชัน การกำกับ งานกล้อง และเพลงทั้งหมดไว้ภายใน 8kB
  • ซอร์สโค้ดเปิดเผยบน GitHub: ctrl-alt-test/mouton

เครื่องมือที่ใช้กับกราฟิก เพลง และการบีบอัด

  • องค์ประกอบภาพทั้งหมด คำนวณแบบเรียลไทม์บน GPU
    • GLSL shader มีทั้งข้อมูล timeline, การตั้งค่ากล้อง และการแทนฉาก
    • การเรนเดอร์ทำด้วย raymarching
  • shader ถูกย่อด้วย Shader Minifier
  • เพลงสร้างด้วย OpenMPT และซินธิไซเซอร์ 4klang
    • เครื่องดนตรีถูกอธิบายแบบ procedural
    • รายการโน้ตถูกบีบอัด
  • โค้ดเขียนด้วย C++ ใน Visual Studio 2022
  • compiler flag และการ initialize เริ่มจากพื้นฐานของเฟรมเวิร์ก Leviathan
  • ไฟล์ executable สุดท้ายถูกบีบอัดด้วย Crinkler

ทำไมต้อง 8kB

  • ใน demoscene มักมีหมวดจำกัดขนาด เช่น 4kB และ 64kB
  • งานเดิมมักตั้งเป้าไว้ที่ 64kB แต่ 8kB ให้ข้อจำกัดและกฎที่แตกต่างไปอย่างสิ้นเชิง
  • เทคนิคของ intro ขนาด 4kB น่าสนใจ แต่ทีมมองว่าจำกัดเกินไปสำหรับ การเล่าเรื่อง อย่างจริงจัง
  • Revision demoparty เพิ่มหมวดแข่งขัน 8kB เมื่อไม่กี่ปีก่อน และทีมมองว่าเป็นโอกาสที่ดีในการทดลอง

โลกที่วาดด้วยสามเหลี่ยมสองรูป

  • เช่นเดียวกับวิธีมาตรฐานที่ใช้ใน demoscene ตั้งแต่ปี 2008 เป็นต้นมา ทีมวาดสี่เหลี่ยมที่ครอบคลุมทั้งหน้าจอด้วย สามเหลี่ยมสองรูป
  • บนสี่เหลี่ยมนี้ GLSL shader จะคำนวณสีของแต่ละพิกเซลและแต่ละเฟรม
  • ฟังก์ชัน shader รับพิกัดและเวลาเป็น input แล้วส่งค่าสีกลับมา
  • ความท้าทายหลักคือจะแทนแกะและฉากทั้งหมดภายในฟังก์ชันนี้อย่างไร

สร้างฉากด้วย SDF

  • signed distance field (SDF) คือฟังก์ชันที่คำนวณระยะจากจุดหนึ่งในอวกาศไปยังวัตถุที่ใกล้ที่สุด
    • บนผิววัตถุจะคืนค่า 0
    • ภายในวัตถุจะคืนค่าติดลบ
  • รูปทรงพื้นฐานอย่างทรงกลมหรือกล่องสามารถแทนได้ด้วยสมการง่ายๆ
  • ฉากถูกสร้างโดยผสาน distance field หลายชุดเข้าด้วยกัน
    • union ของวัตถุสองชิ้นสร้างได้ด้วยค่าระยะที่น้อยที่สุด
    • intersection สร้างได้ด้วยค่าที่มากที่สุด
    • หากใช้ smooth union จะสร้างรูปทรงที่ดูเป็นธรรมชาติมากขึ้นได้
  • แกะถูกสร้างจากการประกอบและผสานรูปทรงง่ายๆ เช่น กรวยและทรงกลม ส่วนลำตัวและขนสร้างด้วย ฟังก์ชัน noise 3D

วิธีตัดสินพิกเซลด้วย raymarching

  • raymarching คือเทคนิคเรนเดอร์ที่ใช้ SDF เพื่อค่อยๆ เดินรังสีไปข้างหน้าในฉาก 3D
  • ไม่ได้คำนวณจุดตัดทางคณิตศาสตร์โดยตรงเหมือน ray tracing แบบดั้งเดิม
  • SDF บอกระยะที่สามารถเคลื่อนที่ได้โดยไม่ชนวัตถุ จากนั้นจึงเลื่อนรังสีไปข้างหน้าตามระยะนั้นซ้ำๆ
  • เมื่อระยะกลายเป็น 0 หรือใกล้ 0 จะถือว่าพบจุดตัดแล้ว
  • เมื่อเกิดจุดตัด ก็รู้ได้ว่าพิกเซลปัจจุบันเป็นของแกะ ท้องฟ้า หรือวัตถุอื่น
  • การจัดแสงต้องใช้ surface normal และประเมิน normal โดยคำนวณความชันรอบๆ จุดนั้น
  • เงาคำนวณโดยส่งรังสีอีกเส้นจากจุดตัดไปทางดวงอาทิตย์ เพื่อตรวจว่ามีวัตถุอยู่ระหว่างทางหรือไม่

วิธีเล่าเรื่องด้วยพลังการแสดงออกอันจำกัด

  • เดโมไม่มีเสียงพูดหรือตัวอักษร และมีตัวละครเพียงตัวเดียว
  • แกะทำได้แค่เดิน ขยับหัวและตาเล็กน้อย และหมุนตัวไม่ได้ด้วยซ้ำ
  • เพื่อถ่ายทอดอารมณ์ภายใต้ข้อจำกัดนี้ ทีมตัดองค์ประกอบที่ไม่เกี่ยวกับเรื่องออก
    • ตอนแรกคิดถึงทะเลทราย เนินทราย และท้องฟ้า แต่ตัดสินว่าไม่จำเป็นต่อเรื่อง
    • พื้นหลังคงไว้เป็นสีขาวล้วน
    • ลด texture ลง ยกเว้นป้ายและดวงตาที่ใช้สื่อความหมาย
  • ทีมรักษาขอบเขตให้เล็กเพื่อโฟกัสกับ รายละเอียด การขัดเกลา งานกล้อง การตัดต่อ และการซิงก์กับเพลง
  • แต่ละช็อตถูกจัดวางด้วยมือ และแอนิเมชันถูกปรับซ้ำหลายครั้งเพื่อให้ flow ดูเป็นธรรมชาติ

กล้องและการกำกับ

  • กล้องถูกใช้เป็นเครื่องมือเล่าเรื่อง
  • ฉากที่แกะเดินหลงเป็นเวลานานใช้ช็อตกว้างเพื่อสร้างความรู้สึกโดดเดี่ยว
  • จังหวะที่แกะสังเกตเห็นป้าย ใช้ extreme close-up ที่ดวงตา
  • ตอนแกะมองป้าย กล้องค่อยๆ zoom in ไปทางหัวเพื่อเพิ่มสมาธิของผู้ชม
  • ความตื่นเต้นของแกะถ่ายทอดด้วยการซ้อนหลายองค์ประกอบเข้าด้วยกัน
    • เอฟเฟกต์ 2D แบบการ์ตูน
    • ก้าวเดินที่เร็วขึ้น
    • การขยับหางที่ถูกเน้น
    • การส่ายหัวแบบโอเวอร์
    • การเปลี่ยนเพลงอย่างดรามาติก

วิธีพัฒนาเพื่อให้ iterate ได้เร็ว

  • ซอร์สโค้ดมี ค่าคงที่แบบ hardcode จำนวนมาก
    • ขนาดตาของแกะ
    • ความเร็วการเคลื่อนกล้อง
    • ความยาวของแต่ละช็อต
    • ค่าต่างๆ เช่น สีของดอกไม้ ถูกปรับซ้ำไปมา
  • เพื่อ feedback ที่รวดเร็ว ทีม recompile shader ตอน runtime และอัปเดตกราฟิกได้ภายใน 1 วินาที
  • ต้องมี player สำหรับปรับแอนิเมชันและกล้อง
    • pause
    • play
    • ควบคุมเวลา
    • ตรวจดูผลได้ทันทีหลัง live reload shader
  • การรองรับเพลงก็จำเป็นเพื่อซิงก์เพลงกับแอนิเมชันอย่างแม่นยำ
  • prototype แรกสร้างใน Shadertoy จากนั้นย้ายผ่าน KodeLife แล้วเข้าสู่โปรเจกต์ C++

เพลงที่สร้างด้วย 4klang

  • เพลงเป็นองค์ประกอบสำคัญในการเล่าเรื่อง และต้องมีอารมณ์หลายแบบกับการเปลี่ยนผ่านในจังหวะเฉพาะ
  • ทีมใช้เครื่องมือแบบเดียวกับที่ใช้ใน intro ขนาด 4kB แต่จัดสรรพื้นที่เพิ่มเพื่อโครงสร้างที่ซับซ้อนขึ้น
  • 4klang synthesizer ให้ปลั๊กอินที่ใช้ในซอฟต์แวร์ทำเพลงได้ และ export ไฟล์ assembly ออกมา
  • ไฟล์ assembly นี้ถูก compile และ link ร่วมกับเดโม
  • เมื่อรันเดโม synth จะสร้างเสียง waveform แบบ procedural ใน thread แยก แล้วส่งไปยัง sound card
  • เพลงเวอร์ชันแรกมีขนาดใหญ่กว่าที่คาด และต้องปรับหลายอย่างเพื่อลดขนาด
    • ลดจำนวนเครื่องดนตรีจาก 16 ชิ้นเหลือ 13 ชิ้น
    • แต่งธีมตอนจบใหม่ให้เข้ากับ tempo ของเพลงทั้งหมด
    • เพิ่มการซ้ำเพื่อให้บีบอัดได้ดี
    • ปรับสิ่งที่แทบไม่รู้สึกด้วยหู เช่น ความยาวโน้ตของเสียงพื้นหลัง เพื่อเพิ่มอัตราการบีบอัด
  • ทีมรักษาโครงสร้างรวมของเพลงไว้ พร้อมลดการสูญเสียคุณภาพให้น้อยที่สุดและประหยัดพื้นที่

แอนิเมชันและการซิงก์เวลา

  • เดโมประเมินทุกอย่างใหม่ทุกเฟรม โดยไม่มีการคำนวณล่วงหน้าหรือ cache
  • แม้จะเสียเปรียบด้าน performance แต่ดีต่อแอนิเมชัน เพราะองค์ประกอบใดๆ ก็เปลี่ยนตามเวลาได้
  • เดโมทั้งหมดประกอบด้วย ช็อตกล้องที่ทำด้วยมือประมาณ 25 ช็อต
  • แต่ละช็อตอธิบายว่าพารามิเตอร์ 18 ตัวเปลี่ยนไปตามเวลาอย่างไร
    • ตำแหน่งของวัตถุแต่ละชิ้น
    • สถานะของแกะ
    • ตำแหน่งกล้อง
    • จุดโฟกัส
    • เป้าหมายที่กล้องมอง เป็นต้น
  • ตัวอย่างเช่น แค่บรรทัด camPos = vec3(22., 2., time*0.6-10.); ก็แทนการเคลื่อนที่เชิงเส้นของกล้องในช็อตหนึ่งได้
  • time ไม่ได้หมายถึงเวลาสัมบูรณ์ตั้งแต่เริ่มเดโม แต่หมายถึงเวลาตั้งแต่เริ่มช็อตนั้น
    • เมื่อต้องแทรก ลบ หรือปรับช็อต จึงกระทบส่วนอื่นของเดโมน้อยลง
  • การ interpolate แบบเส้นตรงธรรมดาอาจดูเป็นกลไกเกินไป จึงใช้ smoothstep ในหลายกรณี
  • โค้ด timeline อยู่ใน vertex shader
  • นิยามช็อตมีโค้ดซ้ำจำนวนมาก แต่ความซ้ำช่วยให้บีบอัดได้ดี

Texture และ material

  • ใน renderer แบบดั้งเดิม จะนำ texture 2D ไปแปะบนผิวของโมเดล 3D
  • ในวิธี raymarching การคำนวณพิกัด texture ทำได้ยาก จึง คำนวณ texture 3D ขึ้นทันที แทน
  • เมื่อ raymarcher พบตำแหน่ง 3D ที่จะเรนเดอร์ ก็ส่งพิกัด 3D นั้นเข้าไปยังฟังก์ชัน texture
  • ป้ายจราจรสร้างเส้นขอบสามเหลี่ยมหรือสี่เหลี่ยมด้วยคณิตศาสตร์ และวาดเนื้อหาภายในด้วยการผสานหลายฟังก์ชัน
    • สัญลักษณ์ร้านอาหารประกอบจากรูปวงรีสีดำ 4 รูป และรูปสีขาว 2 รูปที่ทำหน้าที่เป็นร่อง
  • เพื่อเพิ่มความหลากหลายทางภาพ ไม่ได้ตั้งค่าเฉพาะ texture แต่ยังตั้งค่า material ให้ต่างกันด้วย
    • เช่น กีบของแกะถูกทำให้มีการสะท้อนต่างออกไปโดยใช้ค่า Fresnel

เงาสะท้อนปลอมที่ทำให้ดวงตามีชีวิต

  • ระหว่างพัฒนา ดวงตาดูไร้ชีวิตและแบนอยู่นาน
  • ดวงตาเป็นองค์ประกอบสำคัญของการออกแบบตัวละครและการเล่าเรื่อง
  • จากภาพอ้างอิงตัวการ์ตูนพบว่าแม้หลายตัวจะมีม่านตา แต่ไม่ใช่สิ่งจำเป็น และรูม่านตามักถูกวาดให้ใหญ่เสมอ
  • เพื่อสร้างดวงตาที่แวววาว จำเป็นต้องมีแสงสะท้อนภายในดวงตา
  • สมการแสงเดิมให้แสงสะท้อนเฉพาะเมื่อดวงอาทิตย์และกล้องอยู่ในตำแหน่งหนึ่งเท่านั้น
  • เพื่อชดเชย ทีมปรับเวกเตอร์ surface normal เพื่อเพิ่มโอกาสเกิด reflection จากดวงอาทิตย์
  • นอกจากนี้ยังใช้ environment mapping
    • โดยทั่วไปในเกมใช้เพื่อลดความซับซ้อนและ optimize reflection ของสภาพแวดล้อมจริง
    • ในที่นี้ แม้โลกจริงจะเกือบเป็นสีขาวล้วน แต่ใช้ texture เพื่อเพิ่มรายละเอียดปลอม
  • ตาขาวและรูม่านตามี reflection ที่ซับซ้อนกว่าโลกว่างเปล่ามาก
    • แหล่งกำเนิดแสงปลอมหลายจุด
    • gradient ที่เลียนแบบพื้นดินมืดและท้องฟ้าสีฟ้า

Post-processing และสไตล์ภาพ

  • บรรยากาศสุดท้ายและคุณภาพภาพถูกขัดเกลาในขั้นตอน post-processing
  • post-processing ที่ใช้มีดังนี้
    • color grading
    • gamma correction
    • vignette อ่อนๆ
    • ฟิลเตอร์ FXAA แบบ 2 pass เพื่อลด aliasing
  • เอฟเฟกต์บางอย่าง เช่น เอฟเฟกต์ดาวในดวงตาหรือเอฟเฟกต์หน้าจอตอนจบ ก็ทำในขั้นตอน post-processing เช่นกัน
    • เอฟเฟกต์เหล่านี้เป็น 2D ล้วนๆ และไม่มีอยู่ในโลก 3D
  • ครั้งหนึ่งเคยทดลองสไตล์การ์ตูนเก่า
    • edge detection เพื่อให้ดูเหมือนวาดมือ
    • เรนเดอร์ขาวดำ
    • grain และ noise
  • หลังหารือกัน ทีมเลิกการทดลองนี้และโฟกัสกับรูปลักษณ์ที่สะอาดและทันสมัยกว่า

การบีบอัด Crinkler

  • แนวคิดหลักคือไม่เก็บข้อมูล แต่เก็บโค้ดที่สร้างข้อมูล
  • เพลงเก็บรายการโน้ตที่จะเล่นและรายการคำสั่งของแต่ละเครื่องดนตรี
  • Crinkler คือเครื่องมือบีบอัดที่ออกแบบมาสำหรับ demoscene และ intro ขนาด 1kB~8kB
  • เนื่องจากไฟล์ executable ต้องแตกไฟล์ตัวเองได้ Crinkler จึงมีโค้ด assembly ขนาดเล็กที่ใช้คลายส่วนที่เหลือของ executable
  • Crinkler ให้ความสำคัญกับการ optimize ขนาด
    • อัลกอริทึมบีบอัดใช้เวลานาน
    • การคลายบีบอัดค่อนข้างช้า
    • ใช้ RAM หลายร้อย MB
  • แต่ Crinkler เพียงอย่างเดียวยังไม่พอ และต้องย่อเพิ่มเติมเพื่อใส่ซอร์สโค้ด shader ขนาด 42kB เข้าไปใน executable

การปรับปรุง Shader Minifier

  • ซอร์สโค้ด shader ถูกใส่ไว้ใน binary สุดท้าย จึงต้องมีขนาดเล็กที่สุดเท่าที่ทำได้
  • จะย่อด้วยมือก็ได้ แต่จะมีปัญหาด้านการดูแลรักษาและการ iterate อย่างรวดเร็ว
  • Shader Minifier คือเครื่องมือย่อ shader ที่พัฒนามาตั้งแต่ปี 2011
  • มันลบ whitespace และ comment ลดชื่อ variable และทำ transformation อื่นๆ อีกมาก
  • intro ขนาด 8kB มีโค้ดมากกว่า 4kB อย่างมาก จึงเกิดปัญหาใหม่ และทีมต้องหยุดทำเดโมหนึ่งเดือนเพื่อเพิ่มฟีเจอร์ที่จำเป็น
  • เพื่อการย่อที่ดี ต้องใช้ source-to-source compiler ที่คล้าย Closure Compiler ไม่ใช่แค่ minifier ธรรมดา
  • transformation ที่ Shader Minifier ทำมีดังนี้
    • เปลี่ยนชื่อ variable และ function
    • inline variable
    • evaluate expression ค่าคงที่ทางคณิตศาสตร์
    • inline function
    • ลบ dead code
    • รวม declaration
  • การลดขนาดโค้ดเองอย่างเดียวไม่พอ ต้องได้ output ที่เป็นมิตรต่อการบีบอัดด้วย
    • บาง transformation ลดขนาดโค้ด แต่เพิ่มขนาดหลังบีบอัดได้
    • ระหว่างพัฒนาเดโมซ้ำๆ ต้องคอยตรวจขนาดหลังบีบอัดอยู่เสมอ
  • การปรับปรุง Shader Minifier ใหม่ช่วยประหยัดได้ประมาณ 600 ไบต์ ใน binary ที่บีบอัดแล้ว
  • ท้ายที่สุด โค้ด shader ขนาด 42kB หลังย่อและบีบอัดแล้วอยู่ที่ประมาณ 5kB
    • พื้นที่ที่เหลือใส่เพลงและโค้ด C++

ผลลัพธ์ที่สร้างต่อยอดจากงานอื่น

  • เดโมนี้สร้างขึ้นบนงานที่ผู้อื่นทำไว้ เช่น เทคนิค raymarching, ซอฟต์แวร์สร้างเพลง และอัลกอริทึมบีบอัด
  • ทีมหวังว่าฟีเจอร์ใหม่ที่เพิ่มใน Shader Minifier จะช่วยให้สร้างเดโมที่ดีกว่าเดิมได้ในอนาคต
  • หมวด 8kB ให้ความเป็นไปได้มากกว่า 4kB และยังมีความหวังว่าจะได้รับความนิยมมากขึ้น
  • เพื่อเทียบให้เห็นภาพ ข้อความต้นฉบับมีประมาณ 21,000 ตัวอักษร และหากเก็บตรงๆ จะต้องใช้ 21kB

1 ความคิดเห็น

 
GN⁺ 2024-01-25
ความคิดเห็นจาก Hacker News
  • ผมเป็นผู้สร้างภาพยนตร์ต้นฉบับที่หนังเรื่องนี้ได้แรงบันดาลใจมา: https://www.youtube.com/watch?v=khWXdkryBE4
    ต้นฉบับแค่ไฟล์ Blender, SVG และไฟล์เสียงก็มีขนาดระดับ MB แล้ว การที่รีเมกนี้ใส่ลงไปได้ใน 8kB นั้นน่าทึ่งจริง ๆ
    ดีใจที่สัญญาอนุญาต Creative Commons มีประโยชน์จริง ๆ แต่ถ้าใช้ตัวละครเม่นตัวเดิมและเมโลดี้เสียงเดิมด้วยก็คงจะดีกว่านี้

  • Sloot กลับมาแล้ว!!!
    https://en.m.wikipedia.org/wiki/Sloot_Digital_Coding_System

    • Sloot อาจจะทำไม่ได้ก็จริง แต่ อัลกอริทึมบีบอัด ด้านล่างนี้ค่อนข้างได้ผลในการยัดทั้งเรื่องลงไปในไม่กี่ kB
      รวบรวมชาว demoscene มาเยอะ ๆ ให้พวกเขาดูหนัง แล้วขังไว้ในห้องที่มีคอมพิวเตอร์สักพัก
      จะได้ผลดียิ่งขึ้นถ้ามีจอใหญ่ ระบบเสียงใหญ่ ๆ เบียร์ และอาหารขยะ จากนั้นก็รับไฟล์ executable ผลลัพธ์มาได้เลย
    • นั่นยังไม่เท่าไร ขอแนะนำ โปรแกรม 1 ไบต์ ที่พิมพ์ผลงานรวมของ Shakespeare ทั้งชุด:
      a
      อินเทอร์พรีเตอร์ที่เขียนด้วย Rust เพื่อประสิทธิภาพจะประเมินคำสั่ง a แล้วพิมพ์ payload เฉพาะที่ฝังอยู่ใน runtime ออกไปยัง STDOUT
    • “ในปี 1999 เพียงไม่กี่วันก่อนจะลงนามสัญญาขายสิ่งประดิษฐ์ของเขา Sloot เสียชีวิตกะทันหันด้วยอาการหัวใจวาย ไม่พบซอร์สโค้ดกลับคืนมา และเทคโนโลยีรวมถึงคำกล่าวอ้างนั้นก็ไม่เคยถูกทำซ้ำหรือพิสูจน์ยืนยันได้”
      เป็นโชคร้ายอย่างโหดร้ายจริง ๆ สำหรับทุกคน
    • จากการอ่านบทความแบบคร่าว ๆ ผมตีความอย่างรวดเร็วว่า เขาน่าจะอธิบาย อัลกอริทึมแฮช ให้คนที่ไม่ใช่สายเทคนิคเข้าใจผิด
      คนเหล่านั้นคงไม่เข้าใจว่า a) มันเป็นฟังก์ชันทางเดียว และ b) ต่อให้ไม่ใช่ทางเดียว อินพุตหลายค่าก็อาจแมปไปยังแฮชเดียวกันได้
  • วิดีโอ demoscene ค่อนข้างสนุก แต่กลับ ไม่เป็นที่รู้จักอย่างน่าประหลาด
    https://www.youtube.com/playlist?list=PLRQwR4-_0PR9HBI_GZs1nTn7q5LTkGeCN
    ถ้ามีช่องที่แกะภายในออกมาอธิบายด้วยภาพดี ๆ แบบ retro game mechanics ก็คงดี

    • การดูเดโมเป็นวิดีโอ YouTube อาจดูเหมือนโกงนิดหน่อย แต่ตอนนี้ผมระวังการดาวน์โหลดและรันไฟล์ executable แบบสุ่ม ๆ มากกว่าเมื่อ 20 ปีก่อน จึงดีใจที่มีวิดีโอให้ดู
      สมัยที่ยังไม่มีวิดีโอ ต้องรอการคลายบีบอัดและประมวลผลอยู่พอสมควร กว่าจะได้ทึ่งหรือผิดหวัง
      เมื่อก่อนผมดูเดโมเยอะมากช่วงพัก และมันเป็นฉากหลังที่เข้ากับสภาพจิตใจตอนนั้นอย่างสมบูรณ์แบบ
    • เหมือนเป็นโอกาสให้แชร์เดโมที่ผมชอบที่สุดตลอดกาล Still กับ Intrinsic Gravity: https://youtu.be/-ZxPhDC-r3w
    • เห็นด้วย ถ้าได้เห็น โครงสร้างภายใน ของอะไรอย่าง .kkrieger คงสุดยอดมาก
      https://en.wikipedia.org/wiki/.kkrieger
    • ถ้าแก้โจทย์ AGI ได้ ผมอยากเห็น demoscene สำหรับสติปัญญา จะบีบอัดได้แค่ไหนกันนะ?
      ไปไกลกว่านั้น เราจะทำโลกที่ประกอบด้วยเอเจนต์อัจฉริยะหลายตัวให้เล็กได้แค่ไหน?
      เพิ่มเติม: คนที่กดไม่เห็นด้วย พวกคุณไม่ฝันกันหรือ? ยังมีสิ่งที่แฟนตาซีสุด ๆ อย่างบ้าคลั่งรออยู่ข้างหน้าอีกมากมาย
    • นึกถึง shader wars ขึ้นมาเลย
  • รู้ว่าเทคโนโลยีเบื้องหลังต่างกันพอสมควร แต่ทำให้นึกถึง .kkrieger ในอดีต อัด 3D FPS ทั้งเกมลง 96k ได้ เท่มากจริง ๆ
    https://en.m.wikipedia.org/wiki/.kkrieger

  • ถ้าดู demoscene มาเยอะและอ่านวิธีสร้างแล้วจะเริ่มเข้าใจข้อจำกัด และชัดเจนว่าองค์ประกอบอย่างแกะ โดยเฉพาะหน้าตัดทรงกรวยของขา สามารถแทนด้วย สมการ ที่บีบอัดมาก ๆ และทำแอนิเมชันในลักษณะเดียวกันได้
    แต่เท่าที่ผมรู้ เดโมส่วนใหญ่อาศัย GPU และความสามารถเร่ง 3D อันทรงพลัง ขณะที่เดโมสไตล์อนิเมะญี่ปุ่นแบบ 2D ดูเหมือนจะหายากหรือแทบไม่มีเลยในขนาดเล็ก ๆ
    จริง ๆ แล้ว แอนิเมชัน 3D ง่ายกว่าหรือเปล่า?
    เสริมว่า “mouton” ในภาษาฝรั่งเศสแปลว่า “แกะ” และจึงเป็นที่มาของคำว่า “mutton”

    • วิธีที่อธิบายมานั่นเองน่าจะชี้ให้เห็นว่าทำไม 3D ถึงพบได้บ่อยในเดโม รูปทรงเรขาคณิตของ 3D สามารถแทนด้วย สมการรูปแบบปิด ที่ต้องใช้พื้นที่จัดเก็บน้อยมาก
      ในทางกลับกัน วิธีแบบ ‘คณิตศาสตร์’ สำหรับเก็บแอนิเมชันสไตล์ 2D ก็มีประมาณการเก็บเส้นขอบเป็นเส้นโค้ง SVG และใช้อัลกอริทึมเติมพื้นที่สำหรับลงสีบริเวณต่าง ๆ
      คิดคร่าว ๆ แล้ว ส่วนโค้งเส้นเดียวหรือเส้นหนึ่งเส้นอาจกินพื้นที่จัดเก็บเท่ากับคำอธิบายปริมาตรเรขาคณิตทั้งก้อน และถ้าต้องเก็บแอนิเมชันของเส้นโค้งเหล่านั้นด้วย ก็ต้องใช้พื้นที่มากกว่าเมทริกซ์แปลงขนาดเล็กของปริมาตร 3D มาก
      ความซับซ้อนของอัลกอริทึมเรนเดอร์ก็น่าจะเพิ่มขึ้นทั้งในแง่ความซับซ้อนของอัลกอริทึมจริงและความซับซ้อนด้านพื้นที่
      ข้อแม้: การเก็บบิตแมปหลายภาพแล้วเล่นเหมือน flipbook ก็อาจอ้างได้ว่าเป็น ‘คณิตศาสตร์’ หากใช้อัลกอริทึมคลายบีบอัดเชิงกระบวนวิธีที่สร้างเฟรมเต็มจากส่วนต่างของการเปลี่ยนแปลง
      แต่ผมไม่คิดว่ามีวิธีแบบนั้นอยู่ และเมื่อเทียบกับคำอธิบายปริมาตร 3D แล้ว ความต้องการพื้นที่คงมหาศาล
    • แอนิเมชัน 2D ส่วนใหญ่ท้ายที่สุดก็พรรณนาเหตุการณ์ในพื้นที่ 3D ดังนั้นโดยทั่วไปแล้ว การ อธิบายเหตุการณ์ 3D โดยตรง น่าจะง่ายกว่ามาก
  • แม้จะใหญ่กว่า 8kB อยู่หน่อย แต่ถ้าชอบแอนิเมชันเกี่ยวกับแกะที่มืดหม่นเกินคาด ขอแนะนำโอเพนมูวี Cosmos Laundromat ของ Blender Foundation
    หนังของมูลนิธินี้มักจะมืดหม่นอย่างประหลาดสำหรับงานเดโมเทคนิคอยู่เสมอ และเรื่องนี้ผมว่าทำออกมาได้ดีเป็นพิเศษ
    [0] https://www.youtube.com/watch?v=Y-rmzh0PI3c

  • ขอเตือนไว้ก่อนว่า หนังจบด้วยคำว่า “to be continued” และในหน้า Wikipedia เขียนไว้แบบนี้:
    “เดิมทีภาพยนตร์เรื่องนี้ตั้งใจให้เป็นจุดเริ่มต้นของภาพยนตร์ขนาดยาว มีการเขียนบทและออกแบบภาคต่อแบบหนังสั้นไว้แล้ว แต่ไม่ได้เข้าสู่การผลิต ในปี 2020 [ผู้สร้าง] ประกาศว่าหนังเรื่องนี้เพียงเรื่องเดียวจะเป็นทั้งหมดของโปรเจกต์”
    ถ้าไม่อยากเจอความผิดหวังที่ไม่มีวันได้เห็นตอนจบของคอนเซ็ปต์ที่น่าสนใจนี้ อาจจะข้ามไปเลยดีกว่า

    • เกี่ยวกับเรื่องนี้ ขอเสริมตามอำเภอใจว่า ต้องขอบคุณ Netflix ที่เปิดให้ดาวน์โหลดหนังทั้งเรื่องจาก S3 ได้ในรูปแบบลำดับภาพ EXR ไม่บีบอัดจำนวน 18,192 ภาพ
      มีประโยชน์ตอนทดลอง HDR ใน DaVinci Resolve
      [1] https://opencontent.netflix.com/#h.uyzoa2bivz2j
    • คำว่า “มืดมนอย่างประหลาด” ดูจะอธิบายอารมณ์ขันแบบดัตช์ได้ค่อนข้างดี และนั่นก็น่าจะเป็นเหตุผลหลักด้วย
  • 8KB เป็นหมวดหนึ่งของ demoscene มีดัชนีที่รวบรวมผลงานแบบนี้ไว้อย่างดีใน Pouet
    0. https://www.pouet.net/prodlist.php?type%5B%5D=8k&page=1

  • Razor 1911. ความคิดถึงล้วน ๆ

    • เป็นกลุ่มที่เป็นที่รู้จักที่สุดจาก warez กับการแคร็ก รวมถึง ASCII art ในไฟล์ FILE_ID.DIZ และ .nfo
      ทำให้นึกถึงความทรงจำดี ๆ มากมายเมื่อหลายสิบปีก่อน :-)
    • ดีใจที่เห็นว่าพวกเขายังสร้างงานศิลปะเจ๋ง ๆ อยู่ที่ไหนสักแห่ง
  • น่าทึ่งจริง ๆ และชอบที่ภายใต้ข้อจำกัดแบบนี้ เรื่องราวยังตลกและสร้างสรรค์ได้ขนาดนี้ ประทับใจมากจริง ๆ
    อยากฟังรายละเอียดทางเทคนิคเพิ่มเติมว่าใช้ ทริกและการลดทอน แบบไหนบ้างเพื่อลดจำนวนไบต์

    • ถ้าอยากดูการปรับแต่งระดับจิ๋วและกระบวนการทำซ้ำ ให้ดูประวัติ commit ของ repository: https://github.com/ctrl-alt-test/mouton/commits/main/
      ใน commit นี้(https://github.com/ctrl-alt-test/mouton/commit/79d2d1eab7a222b434b7041d8fc9bce4e60524f8) ได้ตัดการเพิ่มประสิทธิภาพออกไป ทำให้ประหยัดไบต์ได้มาก
      เดิมทีอยากคงไว้ แต่ไบต์ไม่พอ และพบว่า GPU รุ่นค่อนข้างใหม่ไม่จำเป็นต้องใช้การเพิ่มประสิทธิภาพนั้น
  • ทั้งตลกและน่าทึ่งสุด ๆ ในที่สุดก็ได้ดู หนังที่เดาตอนจบไม่ออก แล้ว