ทำไมพื้นผิวกำลังสองของกำลังสองเสมอ เกิดอะไรขึ้นถ้าพวกเขาไม่ได้?


53

ทำไมความละเอียดของพื้นผิวในเกมจึงมีกำลังสอง (128x128, 256x256, 512x512, 1024x1024 เป็นต้น) มันจะฉลาดหรือไม่ที่จะประหยัดขนาดไฟล์ของเกมและทำให้พื้นผิวพอดีกับรุ่นที่ UV ไม่ได้ห่อหุ้ม

จะเกิดอะไรขึ้นหากมีพื้นผิวที่ไม่ใช่พลังของทั้งสอง

มันจะไม่ถูกต้องหรือไม่ที่จะมีลวดลายเป็นแบบ 256x512 หรือ 512x1024 หรือสิ่งนี้จะทำให้เกิดปัญหาที่พื้นผิวที่ไม่ได้ใช้กำลังของทั้งสองอาจทำให้เกิด?


9
ตัวอย่างอื่น ๆ ของคุณก็คือพลังของสองไม่ใช่แค่พลังสองอย่างเดียวกัน พลังของทั้งสองทำให้พื้นผิวเหมาะสำหรับฮาร์ดแวร์กราฟิก
MichaelHouse

1
@ Byte56 ฉันคิดว่าเขาหมายถึง 2 ^ nx 2 ^ n texture โดยที่ n แตกต่างจาก 1 ถึงไม่ จำกัด (ไม่ใช่อนันต์จริงๆ)
Robin

โปรดทราบว่าพลังของทั้งสองมีประโยชน์ในการสร้าง mipmaps เล็กน้อย
Pubby

เนื่องจากพื้นผิวล้อมรอบ (แม้ว่าคุณสามารถเลือกสิ่งนี้ใน shader แบบกำหนดเอง) คุณไม่จำเป็นต้องเสียพื้นที่ใด ๆ เพียงแค่ห่อโพลีออน UV ของคุณรอบ ๆ ขอบและคุณสามารถใช้ประโยชน์จากพื้นที่ที่มีอยู่ได้ง่ายขึ้น หากคุณยังไม่มีการกดต้องปลอดภัยที่สุดในการติดกับ width = height = 2 ^ n textures เพราะจะช่วยให้สามารถใช้งานฮาร์ดแวร์ได้หลากหลายในราคากว้างขึ้นด้วยเลย์เอาต์ uv ที่ซับซ้อนกว่าเล็กน้อย
Daniel Carlsson

พวกเขาจะไม่เสมออำนาจของทั้งสอง
Almo

คำตอบ:


49

ทำไมความละเอียดของพื้นผิวในเกมจึงมีกำลังสอง (128x128, 256x256, 512x512, 1024x1024 เป็นต้น)

ตามที่ Byte56 บอกเป็นนัยว่าการ จำกัด ขนาดของ "กำลังสอง" นั้นแต่ละมิติต้องเป็นอิสระกำลังสองไม่ว่าพื้นผิวจะต้องเป็นสี่เหลี่ยมจัตุรัสและมีมิติซึ่งเป็นพลังของสอง

อย่างไรก็ตามสำหรับการ์ดที่ทันสมัยและ API กราฟิคที่ทันสมัย ​​"ข้อ จำกัด " นี้ได้รับการผ่อนคลายอย่างมีนัยสำคัญเช่นนั้นขนาดของพื้นผิวอาจมีเหตุผลเพียงเกี่ยวกับสิ่งที่คุณต้องการ อย่างไรก็ตาม:

มันจะฉลาดหรือไม่ที่จะประหยัดขนาดไฟล์ของเกมและทำให้พื้นผิวพอดีกับรุ่นที่ UV ไม่ได้ห่อหุ้ม จะเกิดอะไรขึ้นหากมีพื้นผิวที่ไม่ใช่พลังของทั้งสอง

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

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


11
"มันเป็นความจริงที่คุณ" เสีย "พื้นที่บางส่วนด้วยวิธีนี้ แต่พื้นที่พิเศษมักจะคุ้มค่าสำหรับการแลกเปลี่ยนในการแสดงผล" - ประมาณสิบปีที่ผ่านมาฉันทำงานในสตูดิโอที่นำเกม PS2 ไปที่ XBox ในขณะที่ PS2 ไม่สนับสนุนพื้นผิวที่ไม่ได้ใช้กำลังสองทางเทคนิคในบางกรณีคุณสามารถบังคับให้ทำเช่นนั้นด้วยการจัดการที่ชาญฉลาดเล็กน้อยและไม่มีการสูญเสียความเร็ว XBox ตรงกันข้ามไม่สนับสนุนอย่างสมบูรณ์ ผลลัพธ์ที่ได้คือแม้ว่า XBox จะมี RAM เกือบสองเท่าของ PS2 แต่เราต้องลดขนาดของพื้นผิวลงเพื่อให้พอดี
ZorbaTHut

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

1
@salmonmoose: ถูกต้อง; JPEG บีบอัดแต่ละบล็อกของ 8x8 อย่างอิสระและจะบล็อกบล็อกบนขอบ แต่นั่นไม่เกี่ยวข้องกับคำถามนี้
MSalters

1
JPEG ถูกเข้ารหัสในบล็อค 8x8 ใช่ นั่นไม่ใช่การพิจารณาที่มีประสิทธิภาพ และมันก็ไม่จำเป็นต้องเป็นกำลังของ 2 เช่นกัน :)
Kylotan

ตัวอย่างอยู่บน Android ซึ่งบ่อยครั้งที่พื้นผิวที่ไม่ใช่ poweroftwo ส่งผลให้เกิดพื้นผิวสีขาว
user717572

17

ทำไมพื้นผิวกำลังสองของกำลังสองเสมอ

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

  • โดยทั่วไปแล้วพื้นผิวไม่จำเป็นต้องเป็นรูปสี่เหลี่ยม - แม้ว่า DirectX จะมีD3DPTEXTURECAPS_SQUAREONLYความสามารถ แต่ฉันได้ทำงานกับพื้นผิวที่ไม่เป็นรูปสี่เหลี่ยมจัตุรัสแม้ในฮาร์ดแวร์รุ่นเก่าที่ไม่มีปัญหา
  • พื้นผิวควรเป็นพลังของทั้งสองเพราะการ์ดกราฟิกรุ่นเก่าจำนวนมากยังคงต้องการมันอยู่ สาเหตุของข้อ จำกัด นั้นคือเพื่อให้สามารถทำการปรับแต่งบางอย่างเพื่อการดำเนินการจับคู่พื้นผิว การ์ดกราฟิกที่ทันสมัยส่วนใหญ่ไม่มีข้อ จำกัด นี้เช่นกัน

12
ควรสังเกตว่า "กราฟิกการ์ดรุ่นเก่า" นั้นหมายถึงสิ่งที่ทำก่อนปี 2549 หรือมากกว่านั้น
Nicol Bolas

1
@ NicolBolas ขอบคุณจริง ๆ แล้วฉันพยายามหาข้อมูลอ้างอิงบางอย่างจากจุดนั้น
David Gouveia

7

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

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


6

ปัญหาคือฮาร์ดแวร์บางตัวมีข้อ จำกัด ในการรองรับพื้นผิวที่ไม่มีพลังของสองมิติ

ตัวอย่างเช่นดูที่ด้านล่างของhttp://msdn.microsoft.com/en-us/library/windows/desktop/ff476876%28v=vs.85%29.aspxและอ่านเชิงอรรถ 3 และ 4 ที่นั่น

3ที่ระดับคุณลักษณะ 9_1, 9_2 และ 9_3 อุปกรณ์แสดงผลสนับสนุนการใช้พื้นผิวแบบ 2 มิติที่มีขนาดที่ไม่ใช่พลังของสองภายใต้สองเงื่อนไข ขั้นแรกสามารถสร้าง MIP-map ได้เพียงระดับเดียวสำหรับแต่ละพื้นผิวและอย่างที่สองไม่อนุญาตให้ใช้โหมดการสุ่มตัวอย่าง wrap สำหรับพื้นผิว (นั่นคือสมาชิก AddressU, AddressV และ AddressW ของ D3D11_SAMPLER_DESC) เป็น D3D11_TEXTURE_ADDRESS_WRAP

4ที่ระดับคุณสมบัติ 10_0, 10_1 และ 11_0 อุปกรณ์แสดงผลสนับสนุนการใช้พื้นผิว 2 มิติโดยไม่มีเงื่อนไขซึ่งมีขนาดที่ไม่ใช่พลังของทั้งสอง


6

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

เฟรมบัฟเฟอร์ประกอบด้วยชิ้นส่วนที่เป็นรูปสี่เหลี่ยมจัตุรัส ตัวอย่างเช่นในหน้าจอที่มีความละเอียด 800x600 และพื้นที่สี RGB (0-255) มี 800x600 จุดที่มี 3 ไบต์แต่ละช่องมียอดรวม 3x800x600 = 1,440,000 ไบต์เพื่อระบุที่อยู่ในเฟรมบัฟเฟอร์ นั่นหมายความว่ามีชิ้นส่วนที่กำหนดแอดเดรสได้ 1,875 ชิ้นที่มีขนาด 256x256x3 ไบต์ เนื่องจากข้อมูลพื้นผิวเป็นรูปสี่เหลี่ยมมันทำให้การแมปจากเมทริกซ์ GRAM ไปยังเมทริกซ์บัฟเฟอร์หน้าจอง่ายขึ้นอย่างมีนัยสำคัญโดยใช้มาตราส่วนแบบ bicubic ราวกับว่ามันไม่ได้ยกกำลังสองสำหรับด้านที่ยาวกว่าจะต้องใช้เวลามากขึ้นในการคำนวณ ได้สัดส่วน

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

ดังนั้นหากใช้ภาพขนาด 100x1024 และภาพที่ใช้ 1024x1024 นั้นหมายถึงเสีย 946,176 ไบต์ ยิ่งกว่านั้นถ้าจะทำการประพันธ์เนื่องจากช่องอัลฟาจะต้องมีการเพิ่มเพื่อบ่งชี้ว่าข้อมูลการขยายตัวไม่ควรส่งผลกระทบต่อพื้นผิวแบบผสม


นี่เป็นคำอธิบายที่น่าสนใจ (titbit เกี่ยวกับเมทริกซ์จตุรัส) ที่ไม่พบในพลังปกติของ 2 คำตอบ (+1) - คุณช่วยให้การอ้างอิงบางอย่างได้ไหม?
Samaursa

1

โลกดิจิตอลของเราทำงานด้วยเลขฐานสองจากนั้นคูณหรือหารด้วย 2 ค่าคุณสามารถ "ย้าย" ค่าไปทางซ้ายหรือขวาเช่น

<<  Left shift      x = 5 << 1    0101 << 1     1010     10
>>  Right shift     x = 5 >> 1    0101 >> 1     0010      2

การทำงานกับค่า "กำลังสอง" นั้นง่ายกว่าสำหรับ CPU


0

ฮาร์ดแวร์ที่ทันสมัยสามารถ (สุดท้าย) รับมือกับการเปิดใช้งานโหมดห่อกับอำนาจที่ไม่ใช่ของสองพื้นผิวตาม แต่ไม่ใช่อำนาจของสองพื้นผิวยังคงมีแนวโน้มที่จะเสียหน่วยความจำ GPU ที่พวกเขามีแนวโน้มที่จะได้รับเบาะขึ้นพร้อมความกว้างโดยบางส่วนจำนวนเฉพาะฮาร์ดแวร์ (อย่างใดอย่างหนึ่ง สำหรับขนาดของกระเบื้องบางส่วนหรือปัดเศษขึ้นให้กับกำลังสองขนาดถัดไปที่มีพื้นผิว)

เนื่องจากสิ่งนี้ขึ้นอยู่กับฮาร์ดแวร์และโดยทั่วไปผู้ขายจะไม่เข้าไปดูรายละเอียดเฉพาะของสิ่งเหล่านี้สิ่งที่ปลอดภัยที่สุดคือการใช้พลังของสองมิติสำหรับพื้นผิวต่อไปเพื่อไม่ให้เปลืองแรม GPU

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