Quake מהיר של הפוכה שורש מרובע - 💡 Fix My Ideas

Quake מהיר של הפוכה שורש מרובע

Quake מהיר של הפוכה שורש מרובע


המחבר: Ethan Holmes, 2019

הפונקציה שורש מרובע הפוכה (1 / sqrt (x)) משמש באופן משמעותי במהלך לולאה של מנוע המשחק כדי לנרמל את וקטורים לתוך "יחידות" וקטורים עם אורך של 1. וקטורים מנורמל חשובים כי כאשר אתה לוקח את המוצר נקודה של שניים אותם (Axx * Bx + A * על ידי + AZ * Bz), התוצאה היא הקוסינוס של הזווית בין שני וקטורים.

אז לדמיין יש לך וקטור המתאר את הדרך שבה פני השטח פונה (על פני השטח שלה) ואת השני וקטור המתאר את הכיוון של אור השמש. אם וקטור אור השמש מקביל למשטח שלך רגיל, כלומר לומר את פני השטח מול השמש, את המוצר נקודה של שני וקטורים מנורמל הוא הקוסינוס של 0, שהוא 1. אם פני השטח הוא 90 מעלות מהשמש, מוצר הנקודה הוא הקוסינוס של 90, שהוא 0. בין לבין אתה מקבל ערך בין 0 ל 1, אשר בעצם מאפשר לך לתאר כמה בהיר אתה צריך אור כי פני השטח.

עכשיו, אתה מפעיל את החישוב הזה על כל משולש גלוי במשחק 3D, ואתה עושה את כל זה 30 פעמים או יותר בשנייה, ויש לך נקודת בסיס מקורית אפקט תאורה! כזכור, עם זאת, כי אתה צריך פונקציה כי שורש הפוכה כדי לחשב וקטורים יחידה עבור כל אחד מאותם משולשים. פעולת השורש הריבועי איטית. לעשות את זה אלפי פעמים לכל לולאה לצייר, ויש לך את עצמך משחק איטי.

אבל אם לא אכפת לך לזרוק קצת שולי של דיוק, יש דרך מהירה יותר.

יש פונקציית שורש מרובע הפוכה כי הרבה מנועי משחק להשתמש כי הוא שמועה שמקורם רעידת III על ידי מתכנת Nvidia גארי Tarolli. זה נראה כמו זה:

לצוף InvSqrt (לצוף x) {לצוף xhalf = 0.5f * x; int i = * (int *) & x; / / bts לקבל ערך צף i = 0x5f3759df - (אני >> 1); // נותן ניחוש ראשוני y0 x = * (float *) & i; / / bits להמיר בחזרה לצוף x = x * (1.5f-xhalf * x * x); / / צעד ניוטון, חוזרת מגדילה את החזרת הדיוק x; }

תחזיק מעמד, מה זה?!?!

אז בדרך חזרה, ניוטון בא עם דרך חכמה של קירוב השורש הריבועי ההופכי. ראשית, אתה מחלק את המספר המקורי x בשתיים. בואו קוראים לזה "xhalf". לאחר מכן, אתה עושה לנחש קרוב סביר על השורש הריבועי ההופכי. בואו נקרא לזה G. לאחר מכן, אתה לוקח את שני משתנים אלה לבצע את החישוב (אשר תוכל לזהות את השלב האחרון בפונקציה InvSqrt):

g = g * (1.5 - xhalf * g * g)

אם אתה עושה את זה שוב ושוב, החלפת g מעודכן על כל איטרציה, G יהיה לחדד במהירות על השורש הריבועי ההופכי של X! למעשה, אם אתה בוחר g הגון להתחיל, איטרציה אחת או שתיים תקבלו קרוב מאוד את הערך הנכון.

השאלה היא, איך אתה מוצא כי guesstimate הראשונית עבור G הראשון? המשחק המשחק coders להשתמש טריק עם כמה מספרים נקודה צפה מיוצגים בינארי, עם מעריך ומנטיסה שבור דומה סימון מדעי. ב 32 ביט לצוף, את החלק הכי שמאלי הוא קצת סימן הוא 0 עבור מספרים חיוביים. זה ואחריו 8 סיביות של המעריך (מוטה על ידי 127 לייצג שלילי ושלילי exponents), ואת הסופי 23 סיביות מייצגים את mantissa.

ובכן, כדי לעשות שורש מרובע הפוך, אתה בעצם צריך להכפיל את המעריך על ידי -1/2. כאשר אתה משמרת את אלה ביטים ימינה (פעולה מהירה מאוד), ההשפעה על המעריך היא לחלק אותו על ידי 2. אתה עדיין צריך לחסר את המעריך מ 0 כדי לשנות את זה סימן, אם כי, ומה אתה עושה על מנטיסה אשר הושפע גם בפעולת סיביות?

זה המקום שבו מספר הקסם 0x5f3759df מגיע. זה בהחלט bonkers, אבל על ידי הפחתת תוצאה משמרת קצת מ 0x5f3759df, mantissa הוא reset קרוב למצב המקורי של אותו ואת המעריך הוא מופחת מ 0 (תוך התחשבות זה הטיה של 127) .

התוצאה קרובה מאוד לשורש הריבוע ההופכי. קרוב מספיק עבור אחד לעבור דרך משוואת ניוטון בסופו של דבר עם ערך מדויק מספיק למטרות מעשיות.

הבנת רעידת אדמה מהירה הפוך ריבוע הפוך מהיר שורש הפוך שורש - פרטים מתמטיקה מאחורי מספר הקסם (PDF)



אתה עשוי להתעניין

STEAM אמנות, שנעשו על ידי Makers

STEAM אמנות, שנעשו על ידי Makers


צעצועים, טריקים וטייזרים - מתמטיק של גרדנר

צעצועים, טריקים וטייזרים - מתמטיק של גרדנר


סיור דרך העבר של אמריקה בעבודת יד

סיור דרך העבר של אמריקה בעבודת יד


ITP הצג חורף מצגת

ITP הצג חורף מצגת