رفتن به محتوای اصلی
Koohestun
توضیح کوهستاننمایه‌سازی فضاییمقاله آموزشی· 6 دقیقه مطالعه· در بازی و ورزش‌های الکترونیک

تقسیم بازگشتی در درخت هشت‌تایی (Octree): چگونه نمایه‌سازی فضایی فراخوانی‌های ترسیم را کاهش داده و استریمینگ بی‌وقفه جهان‌باز را ممکن می‌کند

ساختار داده درخت هشت‌تایی (Octree) با تقسیم بازگشتی فضای سه‌بعدی به هشت مکعب تودرتو، به موتورهای بازی‌سازی اجازه می‌دهد تا هندسه نامرئی را در یک چشم‌به‌هم‌زدن حذف کنند. این فیلتر ریاضی، موتور نامرئیِ پشت جهان‌های باز و یکپارچه امروزی است که صفحات بارگذاری را نابود کرده و فراخوانی‌های ترسیم (Draw Calls) پردازنده گرافیکی را به‌شدت کاهش می‌دهد.

به قلم نادر غفاری

معماران موتورهای بازی‌سازی 40%هنرمندان فنی 35%مهندسان سخت‌افزار 25%
معماران موتورهای بازی‌سازی
تمرکز بر گلوگاه فراخوانی ترسیم پردازنده مرکزی و ضرورت مقیاس‌پذیری لگاریتمی برای جهان‌های باز.
هنرمندان فنی
تمرکز بر اینکه چگونه پارتیشن‌بندی فضایی بودجه‌های استریمینگ، گروه‌بندی دارایی‌ها و محدودیت‌های حافظه را دیکته می‌کند.
مهندسان سخت‌افزار
تمرکز بر تغییر رویه به سمت حذف اشیاء مبتنی بر پردازنده گرافیکی و آینده نمایه‌سازی فضایی در سخت‌افزار.

دیدگاه‌هایی که این گزارش پوشش نداده

  • توسعه‌دهندگان مستقل (Indie)
  • متخصصان بهینه‌سازی حافظه

چرا مهم است

بدون نمایه‌سازی فضایی، بازی‌های جهان‌باز مدرن با نرخ فریم تک‌رقمی اجرا می‌شدند و پردازنده مرکزی (CPU) زیر بار محاسبات هندسی خفه می‌شد. درک درخت هشت‌تایی، آن تردستی ریاضی را برملا می‌کند که خلق محیط‌های دیجیتالی عظیم و یکپارچه را روی سخت‌افزارهای خانگی ممکن ساخته است.

وقتی اپیک گیمز (Epic Games) سیستم World Partition موتور آنریل انجین ۵ (Unreal Engine 5) را در سال ۲۰۲۱ مستقر کرد، در واقع تیر خلاص را به صفحات بارگذاری در سراسر صنعت بازی‌سازی زد. این موتور، بارگذاری نقشه‌های مجزا را متوقف کرد و به استریم کردن مختصات روی آورد. ریسک این گذار بسیار بالا بود: یک جهان‌باز مدرن شامل میلیون‌ها شیء مجزاست و ارسال همزمان تمام آن‌ها به پردازنده گرافیکی (GPU) در کسری از ثانیه نرخ فریم را نابود می‌کند. پردازنده مرکزی (CPU) به یک روش بی‌رحمانه و پرسرعت نیاز داشت تا دقیقاً تشخیص دهد بازیکن چه چیزهایی را نمی‌تواند ببیند.[6]

راه‌حل این گلوگاه، نمایه‌سازی فضایی است و برجسته‌ترین فرم سه‌بعدی آن، درخت هشت‌تایی (Octree) نام دارد. مشخصات ویکی‌پدیا در سال ۲۰۰۴ اشاره می‌کند: «درخت‌های هشت‌تایی اغلب برای پارتیشن‌بندی یک فضای سه‌بعدی با تقسیم بازگشتی آن به هشت هشت‌گانه (Octant) استفاده می‌شوند.» این یک فیلتر ریاضی است که به موتور بازی اجازه می‌دهد حجم عظیمی از هندسه را تنها با یک محاسبه دور بریزد و بودجه رندرینگ سخت‌گیرانه ۱۶٫۶ میلی‌ثانیه‌ای را برای حفظ نرخ ۶۰ فریم بر ثانیه حفظ کند.[3]

مکانیک درخت هشت‌تایی بر پایه تقسیم بازگشتی استوار است. موتور بازی یک جعبه احاطه‌کننده (Bounding Box) عظیم را دور کل جهان بازی قرار می‌دهد. اگر این جعبه حاوی بیش از یک آستانه از پیش تعیین‌شده از اشیاء باشد—که اغلب به کمی ۱۰ تا ۵۰ شیء است—جعبه دقیقاً از وسط در امتداد محورهای X، Y و Z به دو نیم تقسیم می‌شود. این کار هشت مکعب کوچک‌تر ایجاد می‌کند. سپس موتور بازی هر یک از این هشت مکعب را ارزیابی می‌کند. اگر یک مکعب فرزند همچنان از محدودیت اشیاء فراتر رود، دوباره به هشت مکعب کوچک‌تر تقسیم می‌شود.[1]

یک حجم واحد به هشت گره فرزند تقسیم می‌شود که آن‌ها نیز می‌توانند بر اساس تراکم اشیاء دوباره تقسیم شوند.

این روند بازگشتی تا زمانی ادامه می‌یابد که هر شیء در جهان بازی به یک گره برگ (Leaf Node) اختصاص یابد—مکعبی آن‌قدر کوچک که تعداد اشیاء درون آن به زیر آستانه مجاز برسد. نتیجه، یک درخت سلسله‌مراتبی از فضاست. مناطق متراکم، مانند یک اتاق داخلی شلوغ، ممکن است ده یا دوازده بار تقسیم شوند و شبکه‌ای فشرده از جعبه‌های کوچک بسازند. مناطق خالی، مانند آسمان باز، ممکن است اصلاً تقسیم نشوند و به‌عنوان یک حجم عظیم و یکپارچه باقی بمانند.[4]

دستاوردهای عملکردی این ساختار، نمایی (Exponential) است. وقتی دوربین بازیکن حرکت می‌کند، موتور بازی فرآیند Frustum Culling را انجام می‌دهد—یعنی بررسی می‌کند کدام اشیاء با میدان دید دوربین تلاقی دارند. بدون درخت هشت‌تایی، پردازنده مرکزی مجبور بود تک‌تک اشیاء موجود در جهان بازی را در برابر مخروط دید دوربین آزمایش کند. در دنیایی با ۱۰۰,۰۰۰ شیء، این یعنی ۱۰۰,۰۰۰ تست تقاطع ریاضی در هر فریم.[2]

اما با درخت هشت‌تایی، موتور بازی دوربین را در برابر جعبه ریشه (Root Box) عظیم آزمایش می‌کند. سپس هشت جعبه فرزند را می‌سنجد. اگر دوربین رو به شمال باشد، چهار جعبه جنوبی فوراً کنار گذاشته می‌شوند. تمام اشیاء داخل آن جعبه‌های جنوبی بدون اینکه تک‌تک بررسی شوند، نادیده گرفته می‌شوند. رابرت نیستروم، مهندس نرم‌افزار، در کتاب الگوهای برنامه‌نویسی بازی می‌نویسد: «پارتیشن فضایی یک ساختار داده است که اشیاء را بر اساس موقعیتشان سازماندهی می‌کند»، و خاطرنشان می‌سازد که هدف، پرس‌وجوی سریع این است که کدام اشیاء در نزدیکی یک مکان خاص قرار دارند.[2]

اما با درخت هشت‌تایی، موتور بازی دوربین را در برابر جعبه ریشه (Root Box) عظیم آزمایش می‌کند.

درخت هشت‌تایی با دور انداختن یک‌باره شاخه‌های کامل درخت، پیچیدگی زمانی پرس‌وجوهای فضایی را از زمان خطی یا O(n) به زمان لگاریتمی یا O(log n) کاهش می‌دهد. پرس‌وجویی که به ۱۰۰,۰۰۰ عملیات نیاز داشت، به حدود ۱۷ عملیات تقلیل می‌یابد. این کارایی همان چیزی است که از غرق شدن پردازنده مرکزی زیر بار فراخوانی‌های ترسیم (Draw Calls)—دستوراتی که از CPU به GPU ارسال می‌شوند تا یک مش (Mesh) خاص را با متریالی خاص رندر کند—جلوگیری می‌کند.[4]

نمایه‌سازی فضایی پیچیدگی زمانی یافتن اشیاء را از زمان خطی به زمان لگاریتمی کاهش می‌دهد.

فراخوانی‌های ترسیم، گلوگاه اصلی در رندرینگ مدرن هستند. در حالی که یک پردازنده گرافیکی مدرن می‌تواند میلیاردها چندضلعی را پردازش کند، پردازنده مرکزی تنها می‌تواند چند هزار فراخوانی ترسیم در هر فریم صادر کند، پیش از آنکه پایپ‌لاین متوقف شود. موتور بازی با استفاده از درخت هشت‌تایی برای حذف تهاجمی اشیاء نامرئی، تضمین می‌کند که تنها هندسه‌ای که مستقیماً جلوی دوربین قرار دارد، یک فراخوانی ترسیم تولید کند.[1]

پیاده‌سازی درخت هشت‌تایی، چالش‌های مهندسی خاص خود را به همراه دارد که عمدتاً مربوط به اشیاء پویاست. هندسه ایستا—مانند زمین، ساختمان‌ها و صخره‌های بزرگ—می‌تواند در طول فاز کامپایل بازی در یک درخت هشت‌تایی پخته (Bake) شود. از آنجا که این اشیاء هرگز حرکت نمی‌کنند، موقعیت آن‌ها در درخت هرگز تغییر نمی‌کند و این امر پرس‌وجوها را به‌طور استثنایی سریع می‌سازد.[5]

اشیاء پویا، مانند بازیکنان، وسایل نقلیه و اشیاء فیزیکی، ساختار را پیچیده می‌کنند. وقتی یک شیء از مرز یک هشت‌گانه به هشت‌گانه دیگر حرکت می‌کند، موتور باید آن را از گره قدیمی حذف کرده و در گره جدید درج کند. اگر یک بازی دارای هزاران پرتابه متحرک باشد، به‌روزرسانی درخت هشت‌تایی می‌تواند دقیقاً همان چرخه‌های پردازشی CPU را مصرف کند که این ساختار برای صرفه‌جویی در آن‌ها طراحی شده بود.[5]

برای کاهش این مشکل، معماران موتورهای بازی‌سازی اغلب از سیستم‌های هیبریدی استفاده می‌کنند. هندسه ایستا در یک درخت هشت‌تایی به‌شدت بهینه‌شده و فقط‌خواندنی (Read-only) قرار می‌گیرد، در حالی که اشیاء پویا در یک شبکه هش فضایی (Spatial Hash Grid) منعطف‌تر و با قابلیت به‌روزرسانی آسان‌تر، یا یک درخت هشت‌تایی ثانویه و کم‌عمق ردیابی می‌شوند. این دوگانگی تضمین می‌کند که جهان ایستا بدون کند کردن شبیه‌سازی فیزیک، به‌صورت یکپارچه استریم شود.[6]

تکنیک Frustum Culling از درخت هشت‌تایی استفاده می‌کند تا بخش‌های کاملی از جهان بازی را که خارج از دید دوربین قرار می‌گیرند، فوراً کنار بگذارد.

درخت هشت‌تایی همچنین نحوه استریم دارایی‌ها از درایو حالت جامد (SSD) به حافظه سیستم را دیکته می‌کند. از آنجا که این درخت ذاتاً اشیاء را بر اساس نزدیکی گروه‌بندی می‌کند، موتور می‌تواند از موقعیت بازیکن در درخت هشت‌تایی استفاده کند تا پیش‌بینی کند کدام دارایی‌ها در مرحله بعد مورد نیاز خواهند بود. اگر بازیکن وارد یک گره والد خاص شود، موتور شروع به بارگذاری بافت‌های با وضوح بالا برای گره‌های فرزند در پس‌زمینه می‌کند و نیاز به صفحه بارگذاری را از بین می‌برد.[4]

در حالی که فناوری‌های جدیدتر بخش زیادی از بار حذف اشیاء (Culling) را با استفاده از سایه‌زن‌های محاسباتی (Compute Shaders) شتاب‌یافته سخت‌افزاری مستقیماً به پردازنده گرافیکی منتقل می‌کنند، نمایه‌سازی فضایی همچنان نقشه بنیادین جهان دیجیتال باقی می‌ماند. پردازنده مرکزی برای مدیریت برخورد فیزیک، انتشار صدا و ناوبری هوش مصنوعی همچنان به تقسیم بازگشتی متکی است. درخت هشت‌تایی تضمین می‌کند که مهم نیست شبیه‌سازی چقدر وسیع شود، سخت‌افزار تنها باید به فضایی که بلافاصله بازیکن را احاطه کرده است فکر کند.[6]

بررسی عمیق دیدگاه‌ها

دیدگاه معماران موتورهای بازی‌سازی

تمرکز بر گلوگاه فراخوانی ترسیم پردازنده مرکزی و ضرورت مقیاس‌پذیری لگاریتمی برای جهان‌های باز.

برای معماران موتور، درخت هشت‌تایی در درجه اول یک مکانیسم دفاعی در برابر پردازنده مرکزی است. در حالی که پردازنده‌های گرافیکی در توانایی خود برای پردازش چندضلعی‌ها به‌طور نمایی رشد کرده‌اند، توانایی پردازنده مرکزی برای صدور فراخوانی‌های ترسیم بسیار کندتر رشد کرده است. معماران، پارتیشن‌بندی فضایی را به‌عنوان لایه ریاضی الزامی می‌بینند که این شکاف را پر می‌کند و تضمین می‌کند دنیایی با میلیون‌ها شیء، در هر میلی‌ثانیه تنها چند هزار شیء را به پایپ‌لاین رندرینگ ارائه دهد.

دیدگاه هنرمندان فنی

تمرکز بر اینکه چگونه پارتیشن‌بندی فضایی بودجه‌های استریمینگ، گروه‌بندی دارایی‌ها و محدودیت‌های حافظه را دیکته می‌کند.

هنرمندان فنی با درخت هشت‌تایی به‌عنوان یک ابزار بودجه‌بندی تعامل دارند. از آنجا که این درخت اشیاء را بر اساس نزدیکی فیزیکی گروه‌بندی می‌کند، نحوه بسته‌بندی بافت‌ها و مدل‌ها برای استریم از SSD را دیکته می‌کند. اگر یک گره برگ حاوی دارایی‌های منحصربه‌فرد و با وضوح بالا بیش از حد باشد، باعث ایجاد لکنت (Stutter) در هنگام عبور بازیکن از آن مرز می‌شود. هنرمندان باید محیط‌هایی بسازند که به آستانه‌های تقسیم‌بندی احترام بگذارند و اطمینان حاصل کنند که تراکم بصری یک صحنه با تراکم ریاضی درخت هشت‌تایی همسو است.

دیدگاه مهندسان سخت‌افزار

تمرکز بر تغییر رویه به سمت حذف اشیاء مبتنی بر پردازنده گرافیکی و آینده نمایه‌سازی فضایی در سخت‌افزار.

مهندسان سخت‌افزار درخت هشت‌تایی را به‌عنوان یک ساختار قدیمی محدود به پردازنده مرکزی (CPU-bound) می‌شناسند که به‌آرامی در حال واگذاری وظایف خود است. با ظهور سایه‌زن‌های مش (Mesh Shaders) و پایپ‌لاین‌های محاسباتی شتاب‌یافته سخت‌افزاری، پردازنده‌های گرافیکی مدرن اکنون می‌توانند حذف فضایی (Spatial Culling) خود را بسیار سریع‌تر از پردازنده مرکزی انجام دهند. با این حال، مهندسان خاطرنشان می‌کنند که پردازنده مرکزی همچنان برای فیزیک، تشخیص برخورد و مسیریابی هوش مصنوعی به درخت هشت‌تایی نیاز دارد، به این معنی که این ساختار حتی با تغییر پارادایم‌های رندرینگ، جزء ثابت توسعه بازی باقی خواهد ماند.

نکات کلیدی

  • درخت هشت‌تایی (Octree) یک دنیای سه‌بعدی بازی را به‌صورت بازگشتی به هشت مکعب کوچک‌تر تقسیم می‌کند تا اشیاء را بر اساس موقعیت مکانی‌شان سازماندهی کند.
  • این نمایه‌سازی فضایی به پردازنده مرکزی اجازه می‌دهد تا هندسه نامرئی را فوراً کنار بگذارد و از ایجاد گلوگاه در فراخوانی‌های ترسیم جلوگیری کند.
  • درخت‌های هشت‌تایی پیچیدگی زمانی پرس‌وجوهای فضایی را از زمان خطی به زمان لگاریتمی کاهش می‌دهند.
  • هندسه ایستا در درخت هشت‌تایی پخته (Bake) می‌شود، در حالی که اشیاء پویا اغلب از شبکه‌های جداگانه و منعطف‌تر برای صرفه‌جویی در چرخه‌های پردازشی استفاده می‌کنند.
  • این ساختار همچنین نحوه استریم دارایی‌ها از حافظه SSD به رم را دیکته کرده و صفحات بارگذاری را حذف می‌کند.

پرسش‌های متداول

درخت هشت‌تایی در توسعه بازی چیست؟

درخت هشت‌تایی یک ساختار داده است که فضای سه‌بعدی را به هشت مکعب کوچک‌تر تقسیم می‌کند و این فرآیند را به‌صورت بازگشتی تکرار می‌کند تا اشیاء را بر اساس موقعیت فیزیکی‌شان سازماندهی کند.

چرا به آن درخت هشت‌تایی (Octree) می‌گویند؟

پیشوند «Oct-» به هشت گره فرزندی اشاره دارد که هر بار با تقسیم یک گره والد ایجاد می‌شوند.

درخت هشت‌تایی چگونه عملکرد بازی را بهبود می‌بخشد؟

این ساختار به موتور بازی اجازه می‌دهد تا بخش‌های بزرگی از جهان بازی را که بازیکن نمی‌تواند ببیند فوراً نادیده بگیرد و تعداد محاسباتی را که پردازنده مرکزی باید انجام دهد به‌شدت کاهش دهد.

آیا بازی‌های دوبعدی از درخت‌های هشت‌تایی استفاده می‌کنند؟

خیر، بازی‌های دوبعدی معمولاً از درخت چهارتایی (Quadtree) استفاده می‌کنند که یک فضای مسطح دوبعدی را به‌جای هشت مکعب، به چهار مربع تقسیم می‌کند.

منابع

پوشش منابع

6 منبع

3 دیدگاه شناسایی‌شده

معماران موتورهای بازی‌سازی 40%هنرمندان فنی 35%مهندسان سخت‌افزار 25%
  1. [1]Game Developerمعماران موتورهای بازی‌سازی

    Octree Partitioning Techniques

    مطالعه در Game Developer
  2. [2]Game Programming Patternsمعماران موتورهای بازی‌سازی

    Spatial Partition

    مطالعه در Game Programming Patterns
  3. [3]Wikipediaمهندسان سخت‌افزار

    Octree

    مطالعه در Wikipedia
  4. [4]Level Up Codingهنرمندان فنی

    Spatial Indexing in Games and Geospatial Applications

    مطالعه در Level Up Coding
  5. [5]Piko3Dمهندسان سخت‌افزار

    Space Partitioning

    مطالعه در Piko3D
  6. [6]تیم سردبیری کوهستان

    تحلیل تیم سردبیری کوهستان

    مطالعه در تیم سردبیری کوهستان

نظرات

همیشه در جریان باشید

هر زاویه. هر روز.

دریافت بازی و ورزش‌های الکترونیک اخبار همراه با پوشش کامل منابع و تحلیل دیدگاه‌ها، مستقیم در صندوق ورودی شما.