เกมทั้งหมดทำโดยการวาดแต่ละเฟรมหรือไม่?


60

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

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


ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
Josh

John Carmack เกือบคิดค้นวิธีการบนพีซีเพื่อทำการเลื่อนด้านข้างแบบเต็มหน้าจอโดยการวาดเพียงชิ้นส่วนแนวตั้งบาง ๆ ของหน้าจอที่มีการเปลี่ยนแปลง พีซีไม่สามารถอัปเดตการแสดงผลเต็มหน้าจอได้เร็วพอโดยไม่มีเทคนิคนี้ เขาใช้สิ่งนี้กับเกม 2d จำนวนมากในช่วงต้นยุค 90 เช่น Commander Keen อ่าน "Masters of Doom" สำหรับข้อมูลเพิ่มเติม
Ash

คำตอบ:


68

เกมเก่ามากใช้เทคนิคที่มีเพียงบางส่วนของเฟรมที่ถูกวาดใหม่ที่เปลี่ยนแปลงบนเฟรมนั้น สิ่งที่ฉันจำได้เกม "Little Big Adventure" ใช้เทคนิคนี้ (1994) แต่คุณจะเห็นได้ว่าเกมนี้ใช้เวลาส่วนใหญ่กับกล้องคงที่ เฉพาะเมื่อคุณย้ายออกจากพื้นที่ที่มองเห็นได้ฉากจะถูกวาดใหม่ ถ้าคุณเล่นเกมคุณจะสังเกตเห็นความล่าช้าเล็กน้อยในเฟรมนั้น สำหรับ GPU ที่ทันสมัยพร้อมเอ็นจิ้นเกมสมัยใหม่สิ่งต่าง ๆ ได้เปลี่ยนไป ทุกอย่างถูกวาดใหม่ในแต่ละเฟรม ขึ้นอยู่กับเทคนิคการเรนเดอร์สิ่งต่าง ๆ อาจแสดงผลหลายครั้ง พลังการคำนวณของ GPU นั้นสูงมากเมื่อคุณใช้อย่างถูกต้อง แต่การนำกลับมาใช้ใหม่กำลังเกิดขึ้น ตัวอย่างเช่นเครื่องยนต์สามารถตัดสินใจที่จะอัพเดทแผนที่เงาทุกเฟรมที่ 5 หรือแสงไม่ได้รับการปรับปรุงตราบใดที่ไม่มีการเปลี่ยนแปลงในแหล่งกำเนิดแสง


22
มันไม่ใช่แค่เกมเก่า ที่ EA มีการผลักดันให้ลดการใช้งานแบตเตอรี่แล็ปท็อปสำหรับเกม "แคชชวล" บางเกมและเทคนิคหนึ่งคือการวาดเฉพาะส่วนต่าง ๆ ของหน้าจอ บางครั้งคุณอาจเห็นสิ่งนี้ใน The Sims 3 หากคุณทิ้งกล้องไว้กับที่และซิมที่เดินผ่านหน้าจอบางครั้งจะมีข้อผิดพลาดที่การวาดใหม่ไม่ใหญ่พอและคุณจะเห็นพิกเซลตกค้างอยู่ในแนว จอภาพ คุณแค่ต้องขยับกล้องเล็กน้อยเพื่อบังคับให้วาดใหม่เต็มและเส้นจะหายไป
ค่าธรรมเนียมของเควิน

12
แก่มาก .. 1994 ... ฉันรู้สึกแก่แล้ว ...
alseether

4
@alseether เก่าในแง่ของการเล่นเกม จำไว้ว่าเราเปลี่ยนจาก blobs พิกเซล 8 บิตเป็น real-photo (ใน cutscenes ที่แสดงผลล่วงหน้าหากไม่ได้แสดงสด) ในเวลาเพียง 20 ~ 30 ปี
Jared Smith

16

เลขที่

อย่างน้อยถ้าคุณมีเกมเก่าจากยุค 70 ที่ใช้เวกเตอร์แสดงอยู่

ตัวอย่างเช่นเกม Asteroids ที่เป็นที่รู้จักอย่างกว้างขวางซึ่ง แต่เดิมได้รับการพัฒนาสำหรับการแสดงผลแบบเวกเตอร์ซึ่งเป็นวิธีที่แตกต่างกันในการเรนเดอร์กราฟิกบนหน้าจอ

จอภาพแบบ Vector นั้นถูกใช้โดยเกมอาร์เคดช่วงปลายทศวรรษ 1970 ถึงกลางทศวรรษ 1980 เช่น Asteroids, Tempest และ Star Wars อาตาริใช้คำว่า Quadrascan เพื่ออธิบายเทคโนโลยีเมื่อใช้ในอาร์เขดวิดีโอเกม

https://en.wikipedia.org/wiki/Vector_monitor

กราฟฟิคสมัยใหม่นั้นค่อนข้าง 100% สำหรับ rasterizaton ซึ่งโดยนิยามแล้วจะเขียนเนื้อหาของบัฟเฟอร์กราฟิกไปยังจอแสดงผลทุกเฟรม


7
การแสดงผลแบบเวคเตอร์นั้นไม่มีแม้แต่ "กรอบ"
ฮอบส์

2
@ ฮอบส์ถูกต้องซึ่งทำให้คำตอบของฉันยังคงถูกต้องตั้งแต่คำตอบของ "เกมทั้งหมดทำโดยการวาดแต่ละเฟรมหรือไม่?" คือ "ไม่ไม่ใช่แม้กระทั่งทุกเกมที่วาดจากเฟรม"
Sandy Chapman

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

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

@SandChapman และอีกระดับมีความแตกต่างกันเล็กน้อย เกมจะอัพเดตหน่วยความจำหน้าจอหรือสไปรต์เมื่อมีบางสิ่งเปลี่ยนแปลง มิฉะนั้นส่วนที่เกี่ยวข้องของจอแสดงผลยังคงอยู่ สิ่งนี้เป็นจริงสำหรับทั้งระบบแรสเตอร์และเวกเตอร์ -“ ดาวเคราะห์น้อย” จัดการการรีเฟรชหน้าจอจากหน่วยความจำหน้าจอ (เวกเตอร์!) โดยไม่รบกวนซีพียูเช่นเดียวกับที่ฮาร์ดแวร์สเปกตรัมของ zx สร้างสัญญาณวิดีโอแรสเตอร์ ไม่ว่าลำแสง crt จริงหรือจินตภาพกำลังวาดรูปหลายเหลี่ยมหรือสแกนหน้าจอในรูปแบบที่ตายตัวเป็นลำดับที่สอง
szulat

11

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

... วิธีการนี้ใช้กับเกม 3 มิติได้อย่างไร ...

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

[1] ... เช่นถ้าคุณเขียนเอนจิ้น [2] ด้วย OpenGL แม้ในกรณีนั้นคุณอาจจัดเก็บสิ่งที่คงอยู่ระหว่างเฟรม

[2] ซึ่งไม่ใช่ตัวเลือกในระดับทักษะปัจจุบันของคุณ


คุณมีการอ้างอิงเพื่อสนับสนุน "ตัวประมวลผลกราฟิกบนเครื่องของคุณจะคำนวณแต่ละเฟรมจากพื้นดินขึ้นมาหรือไม่"?
Kromster

@ Kromster: ส่วนใหญ่เป็นสิ่งที่มีประสิทธิภาพ เนื่องจากแต่ละเฟรมอาจต้องการการคำนวณแบบเต็มรูปแบบและมีความไม่แน่นอนว่าส่วนใดไม่ต้องการคุณจะต้องคำนวณราคาแพงเพื่อกำหนดว่าบิตใดที่สามารถบันทึกได้ แม้ว่ามันจะเป็นการปรับปรุงประสิทธิภาพสุทธิมันจะนำไปสู่อัตราเฟรมที่ไม่สอดคล้องกัน
MSalters

@ การปรับเปลี่ยนวิธีการใช้คำพูดนั้นขัดแย้งกับหลายจุดในคำตอบของเพื่อนบ้านหลาย ๆ
Kromster

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

ฉันไม่แน่ใจด้วยซ้ำว่าสิ่งใดที่จะเป็นการอ้างอิงสำหรับ "หน้าจอต้องถูกล้างออก" แต่มีการอ้างอิงถึงวิธีการแสดงเฟรมใน Doom: adriancourreges.com/blog/2016/09/09/doom-2016- กราฟิกการศึกษา ; อย่าลืมว่าการ์ดกราฟิกระดับสูงที่มีระดับปานกลางควรจะสามารถจัดการการคำนวณต่อล้านล้านต่อวินาทีหลายพันต่อพิกเซล
pjc50

2

คำตอบสั้น ๆ : ไม่

เรื่องยาว:

เมื่อฉันเรียนรู้การเขียนโปรแกรมเกมในโรงเรียนเราได้รับการสอนให้ทำดังต่อไปนี้:

กำหนดอัตราเฟรมต่อวินาทีที่เราต้องการในเกม (ตัวอย่างเช่น 30)

เขียนโค้ดที่เพิ่ม 1 ถึงตัวนับสำหรับแต่ละช่วงเวลา (33 msec สำหรับ 30 fps) รหัสนี้จะทำงานพร้อมกันกับวงเกม

จากนั้นลูปเกมที่ทำการคำนวณสำหรับเกม (อัพเดตสถานะเกม) จะลดตัวนับเดียวกันลง 1 สำหรับแต่ละเฟรม แต่การคำนวณกราฟิกและการวาดภาพไปยังหน้าจอจะทำได้ก็ต่อเมื่อตัวนับนั้นเป็นศูนย์

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

แต่จากนั้นมีหลายสิ่งเกิดขึ้นในเกมซีพียูจะมีงานที่ต้องทำอีกมากและการอัพเดตสถานะของเกมจะถูกจัดลำดับความสำคัญผ่านการวาดลงบนหน้าจอ

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

ทั้งหมดนี้ทำด้วย C ++ และไม่มีเอ็นจิ้นเกมหรือกราฟิกการ์ด ทุกอย่างวิ่งบนซีพียูแกนเดียว เราใช้ไลบรารีบางอย่างสำหรับกราฟิก 2 มิติ


1
ฉันจำเกม "ขวานทองคำ" ได้ เมื่อเล่นเกม 8086 นั้นช้าลงและง่ายต่อการจัดการมากกว่าเล่น 286 ตัวอย่างเมื่อสิ่งต่าง ๆ เคลื่อนที่เร็วขึ้น เพียงแค่ FYI
akostadinov

0

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

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

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

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


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

1
@doppelgreener: แนวคิดของ "การวาด" แต่ละเฟรมค่อนข้างคลุมเครือ มีบางอย่างที่ต้องทำทุกอย่างที่จำเป็นในการสร้างแต่ละเฟรม แต่มีหลายวิธีที่อาจแบ่งงานโดยซีพียูและฮาร์ดแวร์ วิธีการบางอย่างต้องการให้ CPU มีส่วนร่วมในทุกเฟรมแม้ว่าจะมีส่วนต่าง ๆ ของหน้าจอที่ปรากฏเหมือนกันระหว่างหนึ่งเฟรมกับเฟรมถัดไป ในขณะที่เกม LCD หรือ CRT ในที่สุดจะต้องมีสิ่งที่ส่งออกในทุกกรอบที่ไม่ว่างเปล่า [เกมที่ใช้ E-paper หรือการแสดงผล flip-dot อาจไม่] การกระทำที่จำเป็นอาจหรือไม่อาจพิจารณาว่า "วาด"
supercat

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

-11

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


9
มันไม่สมเหตุสมผลกับคำถามที่ถาม .. ฉันคิดว่าคุณมี "เฟรม" สับสนสำหรับสิ่งอื่น ... คุณอาจสับสนกับองค์ประกอบของกระดานเรื่องราวหรือไม่? OP กำลังพูดถึงเฟรมโดยเฉพาะในบริบทของการแสดงผล
Trotski94
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.