สไปรต์เรนเดอร์พร่ามัวด้วยความเร็ว


9

หลังจากเพิ่มความเร็วให้กับเกมของฉันฉันรู้สึกว่าพื้นผิวของฉันกระตุก ฉันคิดว่ามันเป็นแค่ดวงตาของฉันจนกระทั่งในที่สุดฉันก็จับมันเป็นภาพหน้าจอ:

ป้อนคำอธิบายรูปภาพที่นี่

ด้านซ้ายเป็นสิ่งที่แสดงในเกมของฉัน ด้านขวาคือสไปรต์ดั้งเดิมวางอยู่ (นี่เป็นภาพหน้าจอจาก Photoshop, ซูมเป็น 6x)

สังเกตว่าขอบเป็นนามแฝง - ดูเหมือนว่าการเรนเดอร์พิกเซลย่อยเกือบจะเหมือนกัน ในความเป็นจริงถ้าฉันไม่ได้บังคับสไปรต์ของฉัน (ซึ่งมีตำแหน่งและความเร็วเป็น ints) เพื่อวาดโดยใช้ค่าจำนวนเต็มฉันจะสาบานว่า MonoGame กำลังวาดด้วยค่าจุดลอย แต่มันไม่ใช่

อะไรเป็นสาเหตุของสิ่งเหล่านี้ที่ปรากฏพร่ามัว มันจะไม่เกิดขึ้นหากไม่ใช้ความเร็ว

เพื่อความแม่นยำSpriteComponentชั้นเรียนของฉันมีVector2 Positionทุ่งนา เมื่อฉันโทรDrawฉันใช้เป็นหลักnew Vector2((int)Math.Round(this.Position.X), (int)Math.Round(this.Position.Y))สำหรับตำแหน่ง

ผมมีข้อผิดพลาดก่อนที่แม้แต่วัตถุนิ่งจะพร่ามัว - นั่นเป็นเพราะผมใช้ตรงเวกเตอร์และไม่ปัดเศษค่าที่จะPosition intsถ้าฉันใช้Floor/ Ceilingแทนการปัดไปรอบ ๆ sprite / hovers (หนึ่งพิกเซลต่างกัน) และยังคงพร่ามัว


1
สิ่งนี้อาจเกี่ยวข้องกับการกรองพื้นผิวที่ใช้หรือไม่
OriginalDaemon

คุณมีรหัสสำหรับ shader ของคุณหรือไม่? บางคนเพิ่มครึ่งพิกเซลบนแกนทั้งสองเพื่อให้พิกเซลอยู่กึ่งกลาง ไม่แน่ใจว่าฉันคิดว่านั่นเป็น DirectX สิ่งเดียว
William Mariager

3
การปิดใช้งานการกรองเป็นการแก้ปัญหาไม่ใช่วิธีการแก้ปัญหา
Archy

1
การแสดงผลไม่ทราบอะไรเกี่ยวกับความเร็วของคุณดังนั้นตำแหน่งขนาดหรืออะไรก็ตามที่คุณส่งไปยัง SpriteBatch.Draw นั้นแตกต่างกันหรือมีข้อผิดพลาดเกิดขึ้นก่อนที่คุณจะเพิ่มความเร็ว คุณเรียก SpriteBatch.Draw ได้อย่างไร
Archy

1
@ ashes999 คุณทำการแก้ไขข้อบกพร่องในการโทรและตรวจสอบสิ่งนี้ X, this.Y และ this.origin? สิ่งนี้คืออะไรต้นกำเนิดตั้งเป็น? โดยทั่วไปจะไม่มีวิธีที่ผลลัพธ์การแสดงผลจะแตกต่างกันเมื่อการเรียกใช้การวาดนี้เหมือนกัน
Archy

คำตอบ:


3

นี่มันน่าอาย

ปรากฎว่าฉันไม่ได้วาดโดยใช้ตำแหน่งจำนวนเต็ม แต่ตำแหน่งลอย Archy ชี้ให้ฉันเห็นเส้นทางที่ถูกต้องพร้อมกับความคิดเห็นของเขา@ashes999 did you debug this call and checked this.X, this.Y and this.origin?

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

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


1
เสร็จแล้วดีใจที่คุณพบมัน!
Archy

2

XNA ใช้ DirectX9 ซึ่งใช้จุดกึ่งกลางของพิกเซลเป็นตำแหน่ง สิ่งนี้จะสังเกตเห็นได้เมื่อใช้ Vector2 ที่มีการโอเวอร์โหลดของคลาสการวาด ฉันเชื่อว่าการลบ (.5, .5) ควรแก้ไขปัญหาของคุณ

ข้อมูลเพิ่มเติมที่นี่


ฉันไม่สามารถทำสิ่งนี้ได้ในทางเทคนิคเพราะฉันผ่านไปใน Vector2 โดยใช้int, intเป็นอาร์กิวเมนต์ นอกจากนี้สิ่งต่าง ๆ ดูดีอย่างสมบูรณ์แบบเมื่อฉันไม่มีวัตถุใด ๆ ที่เคลื่อนไหว
ashes999

คุณหมายถึงอะไรโดยวัตถุที่มีการเคลื่อนไหว? XNA ไม่มีความคิดเรื่องการเคลื่อนไหวมันดึงสิ่งต่าง ๆ ที่คุณบอกมันด้วย มันเป็นชุดของภาพรวมคงที่ ลองใช้สี่เหลี่ยมผืนผ้าโอเวอร์โหลดเพราะคุณจะปัดเศษเป็นสี่เหลี่ยมมุมฉาก
ClassicThunder

ฉันมีการนำความเร็วมาใช้เอง SpriteComponentมีVector2ตำแหน่งซึ่งเพิ่มขึ้นเป็นลอยขึ้นอยู่กับความเร็ว; เมื่อฉันวาดฉันจะสร้างใหม่Vector2ด้วยpositionX และ Y ของฉันจำนวนเต็มรุ่น (ปัดเศษ) นี่ไม่ใช่ปัญหาเนื่องจากวัตถุเครื่องเขียนที่ไม่มีความเร็วปรากฏได้ดี
ashes999

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

ใช่นั่นคือสิ่งที่ @Archy กำลังพูดด้วย ให้ฉันตรวจแก้จุดบกพร่องและตรวจสอบอีกครั้ง ฉันจะเพิ่มp += vช่วงและแสดงผลด้วยUpdate new Vector2((int)Math.Round(p.X), (int)Math.Round(p.Y)))
ashes999

2

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

คุณตรวจแก้จุดบกพร่องของการโทรนี้และตรวจสอบสิ่งนี้ไหม X สิ่งนี้ Y และสิ่งนี้หรือไม่? สิ่งนี้คืออะไรต้นกำเนิดตั้งเป็น? โดยทั่วไปจะไม่มีวิธีที่ผลลัพธ์การเรนเดอร์ด้วยความเร็วจะแตกต่างกันเมื่อการเรียกการดึงนี้เหมือนกัน


1

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

ตัวอย่างคลาสสิกของเกมที่มีและไม่มีตัวกรองคือ Super Mario 64 ซึ่งมีตัวกรองในขณะที่ Doom ไม่ได้ทำ

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

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

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

นอกจากนี้คุณยังอาจต้องการที่จะอ่านนี้


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

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