Skip to content
Tayakorn
HyperFrames Handbook

HyperFrames Handbook

LEVEL 3 · ระดับสูง

กลไกภายใน: เครื่องถ่ายทีละเฟรม

บทนี้เปิดฝากล่องเครื่องเรนเดอร์ แล้วปริศนาทุกข้อที่เล่มนี้ปลูกไว้จะถูกไขพร้อมกันด้วยเหตุผลเดียว

11.1 ไปป์ไลน์จริงจาก log

เรนเดอร์การ์ด 10 วินาทีหนึ่งรอบ log เล่าไปป์ไลน์ครบ (ตัดมาเฉพาะสาระ):

phase: capture   totalFrames: 300  workerCount: 4  captureMode: beginframe
phase: encode    (FFmpeg เย็บเฟรมเป็นวิดีโอ)
phase: assemble  hasAudio: true  (ผสมเสียง ปิดไฟล์)

จุดที่ควรหยุดอ่านคือ workerCount: 4 — เครื่องเปิดเบราว์เซอร์หลายตัวแบ่งกันถามคนละช่วงเฟรมพร้อมกัน เฟรม 200 อาจถูกถ่ายก่อนเฟรม 50 ไม่มีการ "เล่นจากต้นจนจบ" อยู่ในระบบเลยแม้แต่ขั้นตอนเดียว

เว็บเพจtimeline หยุดนิ่งตอบ f(t) อย่างเดียวworker 1 · เฟรม 1–75worker 2 · เฟรม 76–150worker 3 · เฟรม 151–225worker 4 · เฟรม 226–300ถามพร้อมกัน — ไม่เรียงลำดับcapture · 300 เฟรมencode · FFmpegassemble · +เสียง.mp4อะไรที่ตอบ t เดิมไม่เหมือนเดิม (random · นาฬิกา · network · input) พังตั้งแต่ชั้นนี้
FIG 11.1 ของจริงจาก log การเรนเดอร์: workerCount: 4 — สี่เบราว์เซอร์แบ่งกันถามคนละช่วงเฟรมพร้อมกัน เฟรม 200 จึงอาจถูกถ่ายก่อนเฟรม 50 · จากนั้นสามเฟสตามลำดับ captureencodeassemble (ผสมเสียง) · ไม่มี “เล่นจากต้นจนจบ” อยู่ในระบบแม้แต่ขั้นตอนเดียว — รากของกฎ determinism ทุกข้อ

11.2 ปริศนาทั้งเล่ม ไขด้วยประโยคเดียว

ทุกกฎของ HyperFrames คือผลของข้อเท็จจริงที่ว่า เฟรมถูกถามไม่เรียงลำดับและถามซ้ำได้:

  • ห้าม Math.random() / นาฬิกาจริง / fetch ตอนเรนเดอร์ — ค่าพวกนี้ตอบไม่เหมือนเดิมต่อคำถามเดิม (ปลูกไว้บทที่ 2)
  • ห้ามเพจเล่นสื่อเอง — เวลาไหลจริงผูกคำตอบกับ "ตอนไหนที่ถาม" (ไขแล้วบทที่ 7)
  • ห้าม animation วนไม่รู้จบ (repeat: -1) — ตำแหน่งในลูปนิยามจากเวลาไม่ได้ถ้าไม่รู้จำนวนรอบ ใช้จำนวนจำกัดที่คำนวณจากความยาวจริง (ปลูกไว้บทที่ 2)
  • timeline ต้อง paused และ fromTo ชนะ to — การ "จำสภาพตอนเริ่ม" ขึ้นกับลำดับการถาม (ไขแล้วบทที่ 5)
  • แม้แต่ hover / scroll ก็ต้องห้าม — เครื่องเรนเดอร์ไม่มีมือ ไม่มี input event ใด ๆ

11.3 พิสูจน์เชิงประจักษ์ — hash ไม่โกหก

ผมเติม Math.random() หนึ่งบรรทัดให้เส้นใต้เอียงแบบสุ่ม แล้วถ่ายเฟรมที่ t=5 สองรอบ จากนั้นถอดออกแล้วถ่ายซ้ำอีกสองรอบ เทียบ hash ระดับพิกเซล:

มี Math.random   run1: 98820fd7...   run2: 5490ad2c...   ← คนละภาพ
โค้ดสะอาด        run1: cdaa3183...   run2: cdaa3183...   ← เหมือนกันทุก byte

โค้ดสะอาดตอบ f(t) เดิมเป๊ะทุกครั้งจริง ๆ ไม่ใช่วาทกรรม — และหนึ่งบรรทัดสุ่มทำลายมันทันที ลองเองได้ในหนึ่งนาที: snapshot --at 5 สองรอบแล้วเทียบไฟล์

กฎทุกข้อที่ดู "จุกจิก" ของ framework นี้ คือราคาของสัญญาเดียว: ถามเฟรมไหน เมื่อไหร่ กี่รอบ ก็ได้ภาพเดิม

Read the full book