ในเบราว์เซอร์ควรใช้สเปรดชีทขนาดใหญ่หรือ PNG ที่แตกต่างกัน (10,000) ตัวหรือไม่


33

ฉันกำลังสร้างเกมใน jQuery ที่ฉันใช้แผ่นประมาณ 10,000 32x32 แผ่น จนถึงตอนนี้ฉันใช้มันแยกกันหมด (ไม่มีแผ่นสไปรต์) แผนที่เฉลี่ยใช้ประมาณ 2,000 ไทล์ (บางครั้งใช้ PNG ใหม่ แต่แยก Divs ทั้งหมด) และประสิทธิภาพการทำงานมีตั้งแต่เสถียร (Chrome) ไปจนถึงความล่าช้าเล็กน้อย (Firefox) แต่ละ divs เหล่านี้อยู่ในตำแหน่งที่ใช้ CSS อย่างแน่นอน พวกเขาไม่จำเป็นต้องได้รับการอัพเดททุกเห็บเพียงแค่โหลดแผนที่ใหม่

มันจะดีกว่าหรือที่ประสิทธิภาพจะใช้วิธี spritesheet สำหรับ div โดยใช้การวางตำแหน่งพื้นหลัง CSS เหมือน gameQuery

ขอบคุณล่วงหน้า!


3
คุณต้องใช้แผ่น 10,000 อันสำหรับแผนที่ที่ไหน ฉันแนะนำให้คุณอย่าอัพโหลด / วาดแผนที่ทั้งหมดทางฝั่งผู้ใช้ แสดงเพียงส่วนหนึ่งที่มองเห็นได้ เมื่อผู้ใช้ย้ายโหลดส่วนถัดไป วิธีการทำงานของกราฟิก 3D ทุกรูปแบบ
Deele

แผนที่เฉลี่ยใช้ไทล์ต่างกัน 2000 แบบหรือเพียงแค่รวมเบลดทั้งหมด 2000 แผ่น แผนที่ที่คุณสร้างมีขนาดใหญ่แค่ไหน?
Nick Larsen

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

คำตอบ:


50

คำแนะนำของฉัน

PNG ขนาดเล็กมากเกินไปจะเพิ่มโอเวอร์เฮดของเครือข่ายจำนวนมาก (เนื่องจากขนาดของคำขอ HTTP แต่รวมถึงส่วนหัว PNG และที่สำคัญยิ่งกว่าคือความไม่สามารถบีบอัดได้อย่างมีประสิทธิภาพ) ในอีกทางหนึ่ง PNG ที่มีขนาดใหญ่มากมีข้อบกพร่องที่ต้องใช้เวลาในการโหลดและจำเป็นต้องอยู่ในหน่วยความจำอย่างถาวร (40 เมกะไบต์สำหรับ 10,000 แผ่น) ในหน่วยความจำต่อเนื่อง

ฉันแนะนำ พื้นกลาง: หลาย PNGs ขนาดเหมาะสมตัวอย่างเช่น 1024 กระเบื้องขนาด 32 อาจจัดกลุ่มตามชุดรูปแบบ (ตัวอย่างเช่น PNG ที่มีแผ่นกระเบื้องป่าชุดที่มีแผ่นภูเขาและชุดที่มีแผ่นกระเบื้องเมือง - ฉันไม่รู้ธีมของเกมของคุณ แต่คุณเข้าใจแล้ว)

หมายเหตุเกี่ยวกับประสิทธิภาพของแคช

เนื่องจากประสิทธิภาพการเข้าถึงหน่วยความจำคุณไม่ควรทำให้สไปรต์ของคุณกว้างเกินไป การแบ่งกระเบื้องจากรูปภาพขนาด 128 × 8192 จะเร็วกว่าการตัดออกจากรูปภาพขนาด 8192 × 128 เสมอ

ลองนึกภาพว่าคุณต้องการตัดไทล์แรกในภาพ 8192 × 128 เพื่อความง่ายสมมติว่า 1 พิกเซลคือ 1 ไบต์ พิกเซลสองบรรทัดแรกถูกจัดวางในลักษณะนี้ (เซลล์มีหมายเลขไบต์ในหน่วยความจำ):

┌────┬────┬───┬────┬──────────┬─────┐
  0   1 │...│ 31    ....    8191 1st line of pixels: bytes 0 to 8191
├────┼────┼───┼────┼──────────┼─────┤
81928193│...│8223   ....   16383 2nd line of pixels: bytes 8192 to 16383
├────┼────┼───┼────┼──────────┼─────┤
 ..  .. │...│ ..    ....    ... 

ดังนั้นเพื่อที่จะ blit บรรทัดแรกของชื่อแรกเครื่องมือเบราว์เซอร์จะดึงไบต์031ไป เมื่อต้องการ blit บรรทัดที่สองมันจะดึงข้อมูลไบต์8192ไป8223เรื่อย ๆ จนถึงบรรทัดที่ 32 ที่ไบต์253952ไป253983ถูกดึง

จำนวนไบต์ที่ประมวลผลทั้งหมดจะเท่ากับ 32 × 32 อย่างไรก็ตามช่วงหน่วยความจำทั้งหมดมากกว่า 253984 ไบต์ บน CPU ที่ทันสมัยนี่หมายถึงคอกแคช 32 หรือ 33แผงลอยแคชในทางตรงกันข้ามถ้าภาพเป็น 128 × 8192 ช่วงหน่วยความจำจะเป็นเพียง 4000 ไบต์ซึ่งหมายความว่าไม่เกินสองคอกแคช

เนื่องจาก CPU ของวันนี้เร็วมากแผงขายแคชจึงมีราคาแพงมากและหยุดการคำนวณ ดังนั้นการใช้ภาพ 128 × 8192 แทนภาพ 8192 × 128 จึงน่าจะเร็วเป็น 8 เท่าในทางทฤษฎี ในทางปฏิบัติสิ่งนี้จะขึ้นอยู่กับวิธีการนำ blitting มาใช้: เป็นไปได้ว่าเอ็นจินพื้นฐานนั้นจะแยกภาพเป็นแผ่นกระเบื้องเพื่อลดปัญหา

มันไม่ง่ายที่จะอธิบายอย่างถูกต้องและฉันไม่ได้คาดหวังที่จะอธิบายอย่างละเอียด ฉันหวังว่ามันจะสมเหตุสมผล!


4
"โปรดสังเกตว่าเนื่องจากประสิทธิภาพการเข้าถึงหน่วยความจำคุณไม่ควรทำให้ sprites แผ่นของคุณกว้างเกินไปการตัดกระเบื้องจากรูปภาพ 128 × 8192 จะเร็วกว่าการตัดออกจากรูปภาพ 8192 × 128 เสมอ" - อยากรู้อยากเห็นที่ดีคุณจะทำอย่างละเอียดโปรด? :)
กริมชอว์

@DevilWithin: ฉันพยายามอธิบายปัญหาแล้ว แจ้งให้เราทราบหากฉันชัดเจนพอ!
sam hocevar

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

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

2
@DevilWithin: สิ่งที่ฉันเขียนนั้นใช้ได้กับ CPU เท่านั้น - GPU ที่ขนานกันอย่างหนาแน่นมีการตั้งค่าแคชที่แตกต่างกันมากและจะเก็บพื้นผิวโดยใช้รูปแบบภายในของตัวเองซึ่งเหมาะสำหรับการเข้าถึงแบบสุ่ม นี่คือเหตุผลที่แนะนำให้ใช้สี่เหลี่ยมจัตุรัสพื้นผิวกำลังสองใน OpenGL และฉันจะปฏิบัติตามกฎนั้นสำหรับชุดไพ่ด้วย
sam hocevar

5

spritesheet ขนาดใหญ่หนึ่งอัน (น่าจะ) ให้ประสิทธิภาพที่ดีขึ้นเพียงเพราะสาเหตุที่สำคัญที่สุดประการหนึ่งของความล่าช้าคือการเดินทางไปกลับจากคำขอเบราว์เซอร์ไปยังเซิร์ฟเวอร์ไปยังเบราว์เซอร์ การเรียก HTTP 10,000 ครั้งจะใช้เวลานานกว่าการโทร HTTP 1 ครั้งที่ส่งคืนไฟล์ที่ใหญ่กว่า 10,000 ครั้ง

อาจมีสิ่งอื่น ๆ ที่คุณสามารถใช้เพื่อลดความล่าช้าขึ้นอยู่กับโครงสร้างของเกมและ HTML ที่คุณสร้าง

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