การบีบอัดเดลต้าลดจำนวนข้อมูลที่ส่งผ่านเครือข่ายอย่างไร


26

เกมหลายเกมใช้เทคนิคการบีบอัดเดลต้าเพื่อลดการโหลดข้อมูลที่ส่ง ฉันไม่เข้าใจว่าเทคนิคนี้ลดภาระการโหลดข้อมูลได้อย่างไร

ตัวอย่างเช่นสมมติว่าฉันต้องการส่งตำแหน่ง โดยไม่ต้องบีบอัดเดลต้าผมส่งกับตำแหน่งที่แน่นอนของกิจการเช่นvector3 (30, 2, 19)ด้วยการบีบอัดเดลต้าผมส่งกับตัวเลขที่มีขนาดเล็กvector3(0.2, 0.1, 0.04)

ฉันไม่เข้าใจว่ามันลดการโหลดข้อมูลอย่างไรถ้าทั้งสองข้อความมีvector3- 32 บิตสำหรับแต่ละ float - 32 * 3 = 96 บิต!

ฉันรู้ว่าคุณสามารถแปลงแต่ละ float เป็น byte แล้วแปลงกลับจาก byte เป็น float แต่ทำให้เกิดข้อผิดพลาดที่แม่นยำซึ่งมองเห็นได้


เมื่อใดก็ตามที่คุณกำลังสร้างเครือข่ายกับเกมที่ใช้การบีบอัดเดลต้าในรูปแบบใด ๆ คุณจะต้องกำหนดอย่างสมบูรณ์แบบ (ล้มเหลวและคุณได้รับ desyncs) ไม่ว่า "การแปลงจากไบต์เป็นลอย" (หรืออะไรก็ตาม) ที่ทำให้เกิดข้อผิดพลาดแม่นยำไม่สำคัญ - เงื่อนไขที่จำเป็นคือการมีทุกอย่างเหมือนกันในทุกเครื่อง / เกม หากมี "ข้อผิดพลาดความแม่นยำ" (หลีกเลี่ยงไม่ได้แม้ว่าคุณจะใช้การลอยเต็ม - CPU ของคุณไม่ได้ใช้การลอยเหมือนกับ CPU ของฉัน) พวกเขาจะต้องเหมือนกันในทุกเครื่อง - ดังนั้นจึงไม่สามารถมองเห็นได้ คุณเลือกประเภทเพื่อหลีกเลี่ยงผลกระทบที่มองเห็นได้
Luaan

2
@Luaan หรือคุณสามารถเพิ่มสถานะสัมบูรณ์บางส่วนได้บ่อยครั้งตัวอย่างเช่นคุณสามารถเลือกเอนทิตี้ไม่กี่แห่งและผ่านตำแหน่งสัมบูรณ์ได้เช่นเลือกหน่วยงานที่อยู่ใกล้กับผู้เล่น
วงล้อประหลาดที่

อย่างใดผมคาดหวังว่าคำถามนี้จะเกี่ยวกับความสัมพันธ์ของบางrsync ...
SAMB

Huffman การเข้ารหัส
Ben Voigt

เพียงแค่ใช้คนกลางออกไป
John Demetriou

คำตอบ:


41

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

ด้วยเดลตาคุณจะไม่ส่งตำแหน่งของยูนิตที่ไม่ได้ย้ายเลย นั่นคือจิตวิญญาณของมัน

ลองนึกภาพเราเป็นคนจำนนมาหลายปีแล้วและฉันก็สูญเสียความทรงจำของฉัน (และทิ้งจดหมายทั้งหมดของคุณหลังจากอ่านแล้ว) แทนที่จะเขียนจดหมายของคุณต่อเนื่องตามปกติคุณจะต้องเขียนประวัติชีวิตของคุณทั้งหมดให้ฉันด้วยตัวอักษรตัวใหญ่ตัวหนึ่งอีกครั้งเพื่อให้ฉันทัน

ในกรณีที่คุณกำหนดอาจเป็นไปได้ (ขึ้นอยู่กับ codebase ของคุณ) ใช้จำนวนบิตที่น้อยกว่าในการเข้ารหัส delta เมื่อเทียบกับช่วงบิตขนาดใหญ่ที่จำเป็นในการส่งสถานะเต็ม สมมติว่าโลกอยู่ในระยะทางหลายกิโลเมตรคุณอาจต้องใช้ทุ่น 32 บิตเพื่อเข้ารหัสตำแหน่งอย่างถูกต้องเพื่อพูดหนึ่งเซนติเมตรในแกนที่กำหนด อย่างไรก็ตามด้วยความเร็วสูงสุดที่ใช้กับเอนทิตีซึ่งอาจเป็นเพียงไม่กี่เมตรต่อเห็บมันอาจทำได้ใน 8 บิต (2 ^ 8 = 256 เพียงพอที่จะเก็บสูงสุด 200 ซม.) แน่นอนว่าสิ่งนี้ถือว่าคงที่แทนที่จะใช้จุดลอยตัว ... หรือครึ่งหนึ่ง / สี่ส่วนเหมือนกับใน OpenGL หากคุณไม่ต้องการจุดยุ่งยาก


7
คำตอบของคุณไม่ชัดเจนสำหรับฉัน ฉันรู้สึกเหมือนไม่ส่งข้อมูลของวัตถุที่ไม่เคลื่อนไหวเป็นเพียงผลข้างเคียงของการเข้ารหัสเดลต้าและไม่ใช่ "จิตวิญญาณของมัน" เหตุผลที่แท้จริงในการใช้การเข้ารหัสเดลต้าดูเหมือนว่าจะเน้นในคำตอบของวงล้อประหลาดดีกว่า
Etsitpab Nioliv

14
@EtsitpabNioliv "The Spirit" เป็นเพียง "อย่าส่งสิ่งที่คุณไม่จำเป็นต้อง" สิ่งนี้สามารถนำไปสู่ระดับบิต - "ใช้แบนด์วิดท์มากเท่าที่คุณต้องการเพื่อรับข้อความที่ต้องการผ่านสาย" คำตอบนี้ดูเหมือนชัดเจนสำหรับทุกคน ขอบคุณ
วิศวกร

4
@EtsitpabNioliv เคยเรียนรู้เกี่ยวกับวิธีที่ SVN เก็บไฟล์เซิร์ฟเวอร์ไว้ข้างไหน มันไม่ได้เก็บไฟล์ทั้งหมดที่แต่ละคนกระทำ มันเก็บสันดอนการเปลี่ยนแปลงในแต่ละกระทำมี คำว่า "เดลต้า" มักใช้ในวิชาคณิตศาสตร์และการเขียนโปรแกรมเพื่ออ้างถึงความแตกต่างระหว่างสองค่า ฉันไม่ใช่โปรแกรมเมอร์เกม แต่ฉันประหลาดใจถ้าการใช้นั้นแตกต่างกันมากในการเล่นเกม แนวคิดนี้สมเหตุสมผลแล้ว: คุณ "บีบอัด" จำนวนข้อมูลที่คุณต้องส่งโดยการส่งความแตกต่างแทนที่จะเป็นทุกอย่าง (หากส่วนใดส่วนหนึ่งของฉันสับสนกับฉันมันเป็นคำว่า "บีบอัด")
jpmc26

1
นอกจากนี้ตัวเลขขนาดเล็กมีจำนวนบิตที่สูงกว่าและการใช้อัลกอริทึมการบีบอัดที่เหมาะสมเพื่อเข้ารหัส / ถอดรหัสข้อมูลที่ส่งสามารถนำไปสู่ ​​payload ที่เล็กกว่าแม้จะถูกส่งผ่านเครือข่าย
liggiorgio

22

คุณมีเดลต้าผิด คุณกำลังดูสามเหลี่ยมขององค์ประกอบแต่ละอย่าง คุณต้องคิดถึงเดลต้าของฉากทั้งหมด

สมมติว่าคุณมีองค์ประกอบ 100 รายการในฉากของคุณ แต่มีเพียงหนึ่งในองค์ประกอบที่ย้าย หากคุณส่งเวกเตอร์องค์ประกอบ 100 รายการ 99 รายการจะสูญเปล่า คุณจะต้องส่ง 1 เท่านั้น

สมมติว่าคุณมีวัตถุ JSON ที่เก็บองค์ประกอบเวกเตอร์ทั้งหมดของคุณ วัตถุนี้ซิงค์ระหว่างเซิร์ฟเวอร์ของคุณและลูกค้าของคุณ แทนที่จะตัดสินใจว่า "ทำเช่นนั้นแล้วย้ายไป?" คุณสามารถสร้างเกมขีดถัดไปของคุณในวัตถุ JSON สร้างdiff tick100.json tick101.jsonและส่งข้อมูลนั้น ในฝั่งไคลเอ็นต์คุณใช้ส่วนต่างกับเวกเตอร์ติ๊กปัจจุบันของคุณและคุณพร้อมแล้ว

การทำเช่นนี้คุณใช้ความเชี่ยวชาญมานานหลายทศวรรษในการตรวจจับความแตกต่างของข้อความ (หรือไบนารี!) และไม่ต้องกังวลว่าจะทำอะไรหายไปเอง ตอนนี้คุณควรใช้ไลบรารี่ที่ทำสิ่งนี้อยู่เบื้องหลังเพื่อให้คุณเป็นนักพัฒนาซอฟต์แวร์ได้ง่ายขึ้น


2
การใช้diffเสียงเหมือนแฮ็คที่ไม่มีประสิทธิภาพ การเก็บสตริง JSON ไว้ที่จุดสิ้นสุดการรับการแพตช์และยกเลิกการซีเรียลมันทุกครั้งนั้นไม่จำเป็น การคำนวณความแตกต่างของพจนานุกรมคีย์ - ค่าสองรายการไม่ใช่งานที่ซับซ้อนโดยทั่วไปคุณแค่วนลูปทั้งหมดและตรวจสอบว่าค่าเท่ากันหรือไม่ หากไม่ใช่คุณเพิ่มลงในผลลัพธ์ dict key-value และสุดท้ายคุณส่ง dict ที่ทำให้เป็นอนุกรมไปยัง JSON เรียบง่ายไม่ต้องใช้ความเชี่ยวชาญเป็นปี วิธีนี้: 1) จะไม่รวมถึงข้อมูลเก่า (แทนที่) 2) เล่นได้ดีกว่าด้วย UDP; 3) ไม่ต้องขึ้นบรรทัดใหม่
gronostaj

8
@ gronostaj นี่เป็นตัวอย่างเพื่อให้เข้าใจ ฉันไม่สนับสนุนการใช้ diff สำหรับ JSON - นั่นคือเหตุผลที่ว่า "สมมติ"
corsiKa

2
"การทำเช่นนี้คุณใช้ความเชี่ยวชาญมานานหลายทศวรรษในการตรวจจับความแตกต่างของข้อความ (หรือไบนารี!) และไม่ต้องกังวลเกี่ยวกับการหายไปของตัวเองตอนนี้คุณจะต้องใช้ห้องสมุดที่ทำสิ่งนี้อยู่เบื้องหลัง ง่ายขึ้นสำหรับคุณในฐานะนักพัฒนา " ส่วนนั้นทำให้ดูเหมือนว่าคุณแนะนำให้ใช้ diff หรือใช้ไลบรารีที่ใช้ diff เมื่อไม่มีใครทำสิ่งนั้นอย่างสมเหตุสมผล ฉันจะไม่เรียกการบีบอัดเดลต้า "diffing" มันเป็นเพียงการบีบอัดเดลต้าความคล้ายคลึงกันนั้นเป็นเพียงผิวเผิน
Selali Adobor

diff ที่ดีที่สุดและการบีบอัดเดลต้าที่ดีที่สุดเหมือนกัน ในขณะที่ยูทิลิตี diff บนบรรทัดคำสั่งนั้นเหมาะสำหรับไฟล์ข้อความและอาจไม่ให้ผลลัพธ์ที่ดีที่สุดแก่คุณ แต่ฉันขอแนะนำให้ทำการค้นคว้าไลบรารีที่ทำการบีบอัดเดลต้าให้คุณ ไม่มีอะไรที่แฟนซีเกี่ยวกับคำว่าเดลต้า - เดลต้าและความแตกต่างในแง่นี้หมายถึงสิ่งเดียวกัน ที่ดูเหมือนจะหายไปในช่วงหลายปีที่ผ่านมา
corsiKa

9

บ่อยครั้งกลไกการบีบอัดอื่นจะใช้ร่วมกับการเข้ารหัสเดลต้าเช่นการบีบอัดเลขคณิต

รูปแบบการบีบอัดเหล่านั้นทำงานได้ดีขึ้นมากเมื่อค่าที่เป็นไปได้ถูกจัดกลุ่มเข้าด้วยกันอย่างคาดเดาได้ การเข้ารหัส Delta จะจัดกลุ่มค่าประมาณ 0


1
อีกตัวอย่าง: ถ้าคุณมียานอวกาศ 100 ลำโดยมีตำแหน่งของตัวเอง แต่เดินทางด้วยเวกเตอร์ความเร็วเดียวกันคุณจะต้องส่งความเร็วเพียงครั้งเดียว (หรืออย่างน้อยก็อัดได้ดีจริงๆ ); มิฉะนั้นคุณจะต้องส่ง 100 ตำแหน่งแทน ปล่อยให้คนอื่นทำการเพิ่ม หากคุณพิจารณาการจำลองขั้นตอนการล็อคแบบแบ่งส่วนรัฐนั้นเป็นรูปแบบที่ก้าวร้าวของการบีบอัดเดลต้าคุณไม่แม้แต่จะส่งความเร็ว - เฉพาะคำสั่งที่มาจากเครื่องเล่น ให้ทุกคนเพิ่มของตนเองอีกครั้ง
Luaan

ฉันเห็นด้วย. การบีบอัดมีความเกี่ยวข้องในคำตอบ
Leopoldo Sanczyk

8

คุณถูกต้องในวงกว้าง แต่ขาดจุดสำคัญไปหนึ่งข้อ

หน่วยงานในเกมจะมีการอธิบายโดยหลายลักษณะซึ่งตำแหน่งเป็นเพียงหนึ่ง

คุณลักษณะอะไรบ้าง โดยไม่ต้องคิดมากเกินไปในเกมบนเครือข่ายสิ่งเหล่านี้อาจรวมถึง:

  • ตำแหน่ง.
  • ปฐมนิเทศ.
  • หมายเลขเฟรมปัจจุบัน
  • ข้อมูลสี / แสง
  • ความโปร่งใส
  • รูปแบบการใช้งาน
  • พื้นผิวที่จะใช้
  • เทคนิคพิเศษ.
  • เป็นต้น

หากคุณเลือกสิ่งเหล่านี้แยกกันคุณสามารถทำให้เป็นกรณีได้ว่าในกรอบที่กำหนดใด ๆ ที่จำเป็นต้องเปลี่ยนมันต้องทำการส่งใหม่ทั้งหมด

แต่ไม่ทั้งหมดของเหล่านี้แอตทริบิวต์การเปลี่ยนแปลงในอัตราเดียวกัน

โมเดลไม่เปลี่ยนแปลง หากไม่มีการบีบอัดเดลต้าจะต้องส่งสัญญาณใหม่ ด้วยการรวมเดลต้ามันไม่จำเป็นต้องเป็น

ตำแหน่งและการวางแนวเป็นสองกรณีที่น่าสนใจกว่าปกติประกอบด้วย 3 รอบ ระหว่างสองเฟรมใด ๆ มีความเป็นไปได้ที่จะมีเพียง 1 หรือ 2 ของแต่ละเซ็ต 3 ลอย เคลื่อนที่เป็นเส้นตรง? ไม่หมุน ไม่กระโดด นี่เป็นกรณีทั้งหมดที่ไม่มีการบีบอัดเดลตาคุณต้องส่งสัญญาณใหม่ทั้งหมด แต่ด้วยการบีบอัดเดลต้าคุณต้องส่งใหม่เฉพาะเมื่อมีการเปลี่ยนแปลง


8

คุณมีสิทธิ์ที่จะคำนวณเดลตาด้วยตนเองโดยผลที่เก็บไว้ในโครงสร้างข้อมูลขนาดเดียวกับตัวถูกดำเนินการและส่งโดยไม่มีการประมวลผลเพิ่มเติมใด ๆ จะไม่บันทึกทราฟฟิกใด ๆ

อย่างไรก็ตามมีสองวิธีที่ระบบที่ออกแบบมาอย่างดีบนพื้นฐานของ deltas สามารถประหยัดปริมาณการใช้งานได้

ประการแรกในหลายกรณีเดลต้าจะเป็นศูนย์ คุณสามารถออกแบบโปรโตคอลของคุณได้ถ้าหากเดลต้าเป็นศูนย์คุณจะไม่ส่งเลย เห็นได้ชัดว่ามีค่าใช้จ่ายในการนี้เพราะคุณต้องระบุสิ่งที่คุณเป็นหรือไม่ได้ส่ง แต่โดยรวมก็มีแนวโน้มที่จะชนะใหญ่

ประการที่สอง delta มักจะมีช่วงของค่าน้อยกว่าตัวเลขเดิม และช่วงนั้นจะอยู่กึ่งกลางของศูนย์ สิ่งนี้สามารถใช้ประโยชน์ได้โดยการใช้ชนิดข้อมูลที่เล็กลงสำหรับ delta ส่วนใหญ่หรือโดยการส่งกระแสข้อมูลที่สมบูรณ์ผ่านอัลกอริทึมการบีบอัดวัตถุประสงค์ทั่วไป


6

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

เมื่อเข้ารหัสเวกเตอร์ของตัวเลขคุณสามารถทำได้ในบางกรณี (เช่นจำนวนเต็มจำนวนเต็ม ฯลฯ ) ใช้การเข้ารหัสไบต์ตัวแปรสำหรับแต่ละองค์ประกอบและในบางกรณีคุณสามารถลดจำนวนข้อมูลที่ต้องการแต่ละองค์ประกอบเพิ่มเติม หากคุณเก็บไว้เป็นผลรวมที่กำลังทำงานอยู่หรือเป็นค่าต่ำสุดและความแตกต่างระหว่างแต่ละค่าและค่าต่ำสุดนั้น

ตัวอย่างเช่นถ้าคุณต้องการที่จะเข้ารหัสเวกเตอร์แล้วคุณสามารถเดลต้าเข้ารหัสว่า{68923, 69012, 69013, 69015} {68923, 89, 1, 2}การใช้การเข้ารหัสตัวแปรไบต์เล็กน้อยที่คุณเก็บข้อมูล 7 บิตต่อไบต์และใช้หนึ่งบิตเพื่อระบุว่ามีอีกไบต์มาองค์ประกอบแต่ละรายการในอาร์เรย์จะต้องใช้ 3 ไบต์ในการส่ง แต่เวอร์ชันเข้ารหัสเดลต้า จะต้องใช้ 3 ไบต์สำหรับองค์ประกอบแรกและ 1 ไบต์สำหรับองค์ประกอบที่เหลือ ทั้งนี้ขึ้นอยู่กับประเภทของข้อมูลที่คุณทำให้เป็นอันดับซึ่งจะนำไปสู่การประหยัดที่น่าประทับใจ

อย่างไรก็ตามนี่เป็นการเพิ่มประสิทธิภาพการทำให้เป็นอนุกรมมากขึ้นและไม่ใช่สิ่งที่มีความหมายโดยทั่วไปเมื่อเราพูดถึง "การเข้ารหัสเดลต้า" เมื่อมันมาถึงการสตรีมข้อมูลโดยพลการซึ่งเป็นส่วนหนึ่งของสถานะเกม (หรือวิดีโอหรือสิ่งที่คล้ายกัน) คำตอบอื่น ๆ ก็เพียงพอแล้วที่จะอธิบายว่า


4

นอกจากนี้ยังเป็นที่น่าสังเกตว่าอัลกอริทึมการบีบอัดทำงานได้ดีขึ้นในส่วนต่าง เช่นเดียวกับคำตอบอื่น ๆ ที่กล่าวถึงองค์ประกอบส่วนใหญ่ของคุณยังคงเหมือนเดิมระหว่าง 2 สถานะหรือค่าเปลี่ยนแปลงโดยเศษส่วนเล็กน้อย ในทั้งสองกรณีนี้การใช้อัลกอริทึมการบีบอัดกับความแตกต่างของเวกเตอร์ของตัวเลขทำให้คุณประหยัดได้มาก แม้ว่าคุณจะไม่ได้ใช้ตรรกะเพิ่มเติมใด ๆ กับเวกเตอร์ของคุณเช่นการลบองค์ประกอบ 0

นี่คือตัวอย่างใน Python:

import numpy as np
import zlib
import json
import array


state1 = np.random.random(int(1e6))

diff12 = np.r_[np.random.random(int(0.1e6)), np.zeros(int(0.9e6))]
np.random.shuffle(diff12) # shuffle so we don't cheat by having all 0s one after another
state2 = state1 + diff12

state3 = state2 + np.random.random(int(1e6)) * 1e-6
diff23 = state3 - state2

def compressed_size(nrs):
    serialized = zlib.compress(array.array("d", nrs).tostring())
    return len(serialized)/(1024**2)


print("Only 10% of elements change for state2")
print("Compressed size of diff12: {:.2f}MB".format(compressed_size(diff12)))
print("Compressed size of state2: {:.2f}MB".format(compressed_size(state2)))

print("All elements change by a small value for state3")
print("Compressed size of diff23: {:.2f}MB".format(compressed_size(diff23)))
print("Compressed size of state3: {:.2f}MB".format(compressed_size(state3)))

ซึ่งให้ฉัน:

Only 10% of elements change for state2
Compressed size of diff12: 0.90MB
Compressed size of state2: 7.20MB
All elements change by a small value for state3
Compressed size of diff23: 5.28MB
Compressed size of state3: 7.20MB

ตัวอย่างที่ดี การบีบอัดมีบทบาทที่นี่
Leopoldo Sanczyk

0

หากตำแหน่งของคุณถูกเก็บไว้ใน vector3 แต่เอนทิตีที่แท้จริงสามารถย้ายจำนวนเต็มได้ครั้งละสองสามเท่านั้น จากนั้นส่งเป็นเดลต้าเป็นไบต์จะดีกว่าส่งเป็นจำนวนเต็ม

ตำแหน่งปัจจุบัน: 23009.0, 1.0, 2342.0 (3 float)
ตำแหน่งใหม่: 23010.0, 1.0, 2341.0 (3 float)
เดลต้า: 1, 0, -1 (3 ไบต์)

แทนที่จะส่งตำแหน่งที่แน่นอนทุกครั้งเราส่งเดลต้า


0

การบีบอัดเดลต้าเป็นการบีบอัดของค่าที่เข้ารหัสเดลต้า การเข้ารหัสเดลต้าเป็นการแปลงที่สร้างการกระจายทางสถิติของตัวเลขที่แตกต่าง หากการแจกแจงเป็นไปตามอัลกอริธึมการบีบอัดที่เลือกก็จะลดจำนวนข้อมูลลง มันทำงานได้ดีมากในระบบเช่นเกมที่เอนทิตีย้ายเพียงเล็กน้อยระหว่างการอัพเดตสองครั้ง

สมมติว่าคุณมี 100 เอนทิตีใน 2D บนกริดขนาดใหญ่ 512 x 512 พิจารณาเฉพาะจำนวนเต็มเพื่อประโยชน์เท่านั้น นั่นคือตัวเลขจำนวนเต็มสองตัวต่อหนึ่งเอนทิตีหรือ 200 หมายเลข

ระหว่างการอัปเดตสองครั้งตำแหน่งของเราทั้งหมดจะเปลี่ยนเป็น 0, 1, -1, 2 หรือ -2 มีอินสแตนซ์ของ 0, 33 อินสแตนซ์ของ 1 และ -1 และ 100 อินสแตนซ์เพียง 17 ของ 2 และ -2 นี่เป็นเรื่องธรรมดา เราเลือกการเข้ารหัส Huffman สำหรับการบีบอัด

ต้นไม้ Huffman สำหรับสิ่งนี้จะเป็น:

 0  0
-1  100
 1  101
 2  110
-2  1110

0 ทั้งหมดของคุณจะถูกเข้ารหัสเป็นบิตเดียว นั่นเป็นเพียง 100 บิต 66 ค่าจะถูกเข้ารหัสเป็น 3 บิตและเพียง 34 ค่าเป็น 4 บิต นั่นคือ 434 บิตหรือ 55 ไบต์ บวกกับค่าใช้จ่ายเล็ก ๆ น้อย ๆ เพื่อบันทึกแผนผังการทำแผนที่ของเราเนื่องจากต้นไม้มีขนาดเล็ก โปรดทราบว่าในการเข้ารหัส 5 หมายเลขคุณต้องมี 3 บิต เราทำการซื้อขายที่นี่ความสามารถในการใช้ 1 บิตสำหรับ '0' สำหรับความต้องการใช้ 4 บิตสำหรับ '-2'

เปรียบเทียบสิ่งนี้กับการส่ง 200 จำนวนโดยพลการ หากเอนทิตีของคุณไม่สามารถอยู่ในไทล์เดียวกันคุณเกือบจะรับประกันได้ว่าคุณได้รับการกระจายทางสถิติที่ไม่ดี กรณีที่ดีที่สุดจะเป็น 100 หมายเลขที่ไม่ซ้ำกัน (ทั้งหมดใน X เดียวกันกับ Y ที่แตกต่างกัน) นั่นคืออย่างน้อย 7 บิตต่อหมายเลข (175 ไบต์) และยากมากสำหรับอัลกอริธึมการบีบอัดใด ๆ

การบีบอัดเดลต้าทำงานในกรณีพิเศษเมื่อเอนทิตีของคุณเปลี่ยนเพียงเล็กน้อย หากคุณมีการเปลี่ยนแปลงที่เป็นเอกลักษณ์จำนวนมากการเข้ารหัสเดลต้าจะไม่ช่วย


โปรดทราบว่าการเข้ารหัสและการบีบอัดเดลต้าใช้ในสถานการณ์อื่นที่มีการแปลงอื่นเช่นกัน

MPEG แบ่งภาพเป็นสี่เหลี่ยมเล็ก ๆ และหากส่วนใดส่วนหนึ่งของภาพเคลื่อนไหวเฉพาะการเคลื่อนไหวและการเปลี่ยนแปลงคือความสว่างเท่านั้นที่จะถูกบันทึก ในภาพยนตร์ 25fps การเปลี่ยนแปลงมากมายระหว่างเฟรมนั้นเล็กมาก อีกครั้งการเข้ารหัสเดลต้า + การบีบอัด ทำงานได้ดีที่สุดสำหรับฉากแบบคงที่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.