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

بافر عمق ۲۴ بیتی: چگونه دقت ممیز شناور، مرزهای رندرینگ را جابه‌جا می‌کند و به جنگ Z پایان می‌دهد

وقتی در بازی‌های عظیم جهان‌باز، کوه‌های دوردست سوسو می‌زنند، موتور گرافیکی در رندر آن‌ها شکست نخورده؛ بلکه از نظر ریاضی اعدادش برای محاسبه عمق ته‌کشیده است. حالا مهاجرت به فرمول Reverse-Z به توسعه‌دهندگان اجازه می‌دهد تا بدون نیاز به ارتقای سخت‌افزار، افق دید را تا بی‌نهایت گسترش دهند.

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

به‌طور خلاصه

  • پدیده Z-fighting زمانی رخ می‌دهد که موتور گرافیکی دقت ریاضی لازم برای تشخیص اینکه کدام‌یک از دو شیء دوردست به دوربین نزدیک‌تر است را نداشته باشد.
  • بافرهای عمق ۲۴ بیتی سنتی از یک فرمول غیرخطی استفاده می‌کنند که ۵۰ درصد از دقت خود را تنها در دو واحد اول فاصله هدر می‌دهد.
  • برای رفع مشکل سوسو زدن در فواصل دور، توسعه‌دهندگان در گذشته مجبور بودند «صفحه نزدیک» (near plane) دوربین را دورتر ببرند، که باعث ناپدید شدن اشیای نزدیک می‌شد.

وقتی در یک بازی عظیم جهان‌باز، کوهی در دوردست به شدت در پس‌زمینه آسمان سوسو می‌زند، سخت‌افزار گرافیکی در رندر کردن هندسه آن کم نیاورده است. بلکه موتور بازی از نظر ریاضی دیگر عددی در بساط ندارد تا تعیین کند کدام صخره جلوی دیگری قرار گرفته است. این پدیده که به Z-fighting معروف است، پیامد مستقیم نحوه ترجمه فضای سه‌بعدی به یک بافر عمق ۲۴ بیتی است.[8]

هر پیکسلی که روی صفحه رندر می‌شود به یک مقدار عمق — یک مختصات Z — نیاز دارد تا تضمین کند اشیای نزدیک‌تر به دوربین، اشیای دورتر را می‌پوشانند. از نظر تاریخی، استاندارد صنعت یک فرمت عدد صحیح ۲۴ بیتی بوده است که دقیقاً ۱۶,۷۷۷,۲۱۶ مقدار عمق گسسته را برای نقشه‌برداری از کل جهان قابل مشاهده ارائه می‌دهد.[3][8]

اگرچه ۱۶.۷ میلیون مقدار از نظر ریاضی رقم عظیمی به نظر می‌رسد، اما مشکل در نحوه توزیع آن‌هاست. رابط‌های برنامه‌نویسی گرافیکی استاندارد مانند OpenGL و DirectX به طور سنتی عمق را با استفاده از یک تابع معکوس (۱/z) محاسبه می‌کنند.[3][7]

این توزیع غیرخطی به این معناست که دقت محاسباتی به شدت در درست جلوی دوربین مجازی متمرکز شده است. در یک تنظیمات استاندارد، دقیقاً ۵۰ درصد از تمام مقادیر عمق موجود، تنها در دو واحد اول فاصله از نقطه دید بازیکن مصرف می‌شوند.[1][5]

بافرهای عمق استاندارد نیمی از دقت خود را در دو واحد اول فاصله مصرف می‌کنند، در حالی که Reverse-Z این دقت را به طور یکنواخت توزیع می‌کند.

تا زمانی که موتور بخواهد کوهی در فاصله ۱۰,۰۰۰ واحدی را رندر کند، ممکن است تنها مشتی مقدار عمق برای اختصاص دادن برایش باقی مانده باشد. اگر دو چندضلعی در یک سطل ریاضی بیفتند، پردازنده گرافیکی (GPU) نمی‌تواند تشخیص دهد کدام‌یک نزدیک‌تر است و همین باعث می‌شود فریم به فریم جایشان با هم عوض شود.[5][8]

مستندات LearnOpenGL اشاره می‌کند که تست عمق یک مفهوم بنیادین در رندرینگ سه‌بعدی است و توضیح می‌دهد که بافر عمق به طور خودکار قطعاتی را که توسط هندسه رندر شده قبلی مسدود شده‌اند، دور می‌ریزد. اما وقتی این دقت در فواصل دور از کار می‌افتد، توسعه‌دهندگان از نظر تاریخی مجبور به یک سازش تلخ بوده‌اند: هل دادن «صفحه نزدیک» (near plane) به فاصله‌ای دورتر از دوربین.[3]

جابه‌جا کردن صفحه نزدیک از ۰.۰۱ واحد به ۰.۱ واحد، میلیون‌ها مقدار عمق را به افق دوردست اختصاص می‌دهد. با این حال، این کار یک مشکل جدید ایجاد می‌کند: اشیایی که بیش از حد به دوربین نزدیک هستند، مانند سلاح یا دستان شخصیت بازی، بریده شده و کاملاً ناپدید می‌شوند.[1][8]

در سال ۲۰۱۲، توسعه‌دهندگان موتور Outerra، یک پلتفرم رندرینگ سیاره‌ای، تحلیل بنیادینی با عنوان «به‌حداکثر رساندن دامنه و دقت بافر عمق» منتشر کردند. آن‌ها نشان دادند که بافرهای عمق لگاریتمی استاندارد برای انتقال یکپارچه از زمین به فضا کافی نیستند و نیازمند یک بازنگری اساسی در نحوه محاسبه عمق هستند.[1]

راه‌حلی که از آن زمان کل صنعت را درنوردیده، یک وارونگی ریاضی به نام «Reverse-Z» است. به جای تنظیم صفحه نزدیک روی ۰.۰ و صفحه دور روی ۱.۰، این مقادیر برعکس می‌شوند.[4][7]

وقتی این تکنیک با یک بافر عمق ممیز شناور ۳۲ بیتی ترکیب می‌شود، Reverse-Z منحنی دقت را از اساس تغییر می‌دهد. اعداد ممیز شناور به طور طبیعی در نزدیکی ۰.۰ دقت بالاتری دارند، زیرا توان (exponent) اجازه می‌دهد تا کسرهای فوق‌العاده کوچکی ساخته شوند.[5][7]

در فواصل بسیار دور، یک بافر Reverse-Z ممیز شناور ۳۲ بیتی به شکل تصاعدی دقیق‌تر از یک بافر عدد صحیح ۲۴ بیتی استاندارد عمل می‌کند.

با تنظیم افق دوردست روی ۰.۰، دقت ذاتی فرمت ممیز شناور به شکلی بی‌نقص افت غیرخطی ۱/z را خنثی می‌کند. این دو منحنی یکدیگر را باطل می‌کنند و نتیجه آن یک توزیع تقریباً کاملاً خطی از مقادیر عمق در سراسر مخروط دید (view frustum) است.[2][5]

در سال ۲۰۱۶، مهندس گرافیک، نیکولاس گیلموت، راهنمای جامعی برای پیاده‌سازی «Reversed-Z در OpenGL» منتشر کرد و ثابت نمود که این تکنیک می‌تواند عملاً Z-fighting را بدون نیاز به معماری‌های سخت‌افزاری جدید از بین ببرد.[7]

البته این گذار بدون دردسر هم نبوده است. پیاده‌سازی Reverse-Z نیازمند بازنویسی شیدرهای رندرینگ هسته و تغییر نحوه مدیریت حذف اشیای پنهان (culling) توسط موتورهاست. همان‌طور که تیم موتور Godot در تیتر معروف آپدیت خود برای این گذار نوشتند: «معرفی Reverse Z (یا همان ببخشید که شیدرتان را خراب کردم).»[4]

در سال ۲۰۲۰، یک تحلیل کمی توسط Zero Radiance برتری ریاضی این تکنیک را تایید کرد و نشان داد که یک بافر Reverse-Z ممیز شناور ۳۲ بیتی حتی در فواصل بسیار دور دقت زیر میلی‌متری خود را حفظ می‌کند و عملاً مشکل رندرینگ جهان‌باز را حل می‌کند.[5]

پدیده Z-fighting زمانی رخ می‌دهد که دو سطح مقادیر عمق مشابهی داشته باشند و بافر دقت کافی برای تمایز قائل شدن بین آن‌ها را نداشته باشد.

تا سال ۲۰۲۱، تیم فنی NVIDIA ابزارهایی برای «تصویرسازی دقت عمق» منتشر می‌کرد و از توسعه‌دهندگان می‌خواست تا برای مدیریت مقیاس عظیم محیط‌های مجازی مدرن، از عمق ممیز شناور ۳۲ بیتی استفاده کنند.[2]

تیم توسعه Evergine در می ۲۰۲۶ تغییرات سطح موتور خود را مستند کرد و خاطرنشان ساخت که «تغییر به Z-Buffer معکوس» یک تکامل ضروری برای پشتیبانی از همزادهای دیجیتال صنعتی عظیم و جهان‌های بازی گسترده بدون آرتیفکت‌های بصری است.[6]

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

با تنظیم صفحه دور (far plane) روی ۰.۰، تکنیک Reverse-Z از دقت ذاتی اعداد ممیز شناور در نزدیکی صفر نهایت بهره را می‌برد.

سقف ریاضی در فاصله رندر برداشته شده است. نقطه عطف قابل‌تایید بعدی برای این صنعت، منسوخ شدن کامل بافرهای عمق ۲۴ بیتی عدد صحیح در APIهای گرافیک موبایل و استانداردسازی Reverse-Z ممیز شناور ۳۲ بیتی در تمام رده‌های سخت‌افزاری است.[8]

اصطلاحات کلیدی

بافر عمق (Z-Buffer)
بلوکی از حافظه گرافیکی که فاصله (مقدار Z) هر پیکسل رندر شده از دوربین را ذخیره می‌کند و برای تعیین اینکه کدام اشیا بقیه را می‌پوشانند استفاده می‌شود.
دقت ممیز شناور
روشی برای نمایش اعداد حقیقی در محاسبات که به ممیز اعشار اجازه «شناور» بودن می‌دهد و دقت عظیمی را برای اعداد بسیار نزدیک به صفر فراهم می‌کند.
مخروط دید (View Frustum)
حجم هرمی‌شکل سه‌بعدی از فضا که نشان‌دهنده آن چیزی است که دوربین مجازی در حال حاضر می‌تواند ببیند و توسط یک صفحه نزدیک و یک صفحه دور محدود شده است.
صفحه نزدیک (Near Plane)
نزدیک‌ترین فاصله به دوربین که در آن اشیا شروع به رندر شدن می‌کنند؛ هر چیزی نزدیک‌تر از آن بریده شده و نامرئی می‌شود.

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

پدیده Z-fighting دقیقاً چیست؟

پدیده Z-fighting یک گلیچ بصری است که در آن دو سطح سه‌بعدی روی هم افتاده به سرعت سوسو می‌زنند، زیرا موتور گرافیکی فاقد دقت ریاضی لازم برای تعیین این است که کدام‌یک به دوربین نزدیک‌تر است.

چرا یک بافر عمق ۲۴ بیتی در فواصل طولانی شکست می‌خورد؟

بافرهای ۲۴ بیتی استاندارد از یک فرمول غیرخطی استفاده می‌کنند که ۵۰ درصد از تمام مقادیر عمق موجود را به دو واحد اول فاصله اختصاص می‌دهد و اعداد بسیار کمی را برای متمایز کردن اشیایی که هزاران واحد دورتر هستند باقی می‌گذارد.

تکنیک Reverse-Z چگونه این مشکل را برطرف می‌کند؟

تکنیک Reverse-Z مقادیر عمق را برعکس می‌کند (افق را به جای ۱.۰ روی ۰.۰ تنظیم می‌کند) و از ریاضیات ممیز شناور استفاده می‌کند که به طور طبیعی در نزدیکی صفر دقت تصاعدی بالاتری دارد و توزیع عمق را کاملاً متعادل می‌کند.

آیا Reverse-Z به کارت گرافیک قدرتمندتری نیاز دارد؟

خیر. این تکنیک به یک بافر عمق ممیز شناور ۳۲ بیتی نیاز دارد که سال‌هاست توسط سخت‌افزارهای استاندارد GPU پشتیبانی می‌شود، اما توسعه‌دهندگان باید شیدرهای هسته موتور خود را برای مدیریت این ریاضیات معکوس بازنویسی کنند.

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

معماران موتور گرافیکی

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

برای توسعه‌دهندگانی که ابزارهای بنیادین صنعت را می‌سازند — مانند تیم‌های پشت Godot، Evergine و Outerra — گذار به Reverse-Z به معنای حذف موارد استثنا (edge cases) است. وقتی یک موتور به یک بافر عدد صحیح ۲۴ بیتی استاندارد متکی است، معماران مجبورند فقط برای پشتیبانی از شبیه‌سازهای فضایی یا جهان‌بازهای عظیم، راه‌حل‌های پیچیده و سرهم‌بندی‌شده‌ای مانند بافرهای عمق لگاریتمی یا رندرینگ چندمخروطی (multi-frustum) بسازند. با استانداردسازی روی یک پایپ‌لاین Reverse-Z ممیز شناور ۳۲ بیتی، آن‌ها یک بوم از نظر ریاضی بی‌نقص را در اختیار بازیسازان قرار می‌دهند که در آن مرتب‌سازی عمق، فارغ از مقیاس، به سادگی کار می‌کند.

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

اولویت دادن به استفاده بهینه از پهنای باند حافظه در عین ارائه فرمت‌های دقت ضروری.

از دیدگاه تولیدکنندگان GPU مانند NVIDIA، دقت عمق یک بازی تعادل با پهنای باند حافظه است. یک بافر عمق ممیز شناور ۳۲ بیتی به ازای هر پیکسل ۳۳ درصد پهنای باند حافظه بیشتری نسبت به یک بافر عدد صحیح ۲۴ بیتی سنتی نیاز دارد. با این حال، مهندسان سخت‌افزار از این تغییر حمایت می‌کنند زیرا هزینه این پهنای باند اضافی بسیار کمتر از هزینه محاسباتی توسعه‌دهندگان بازی برای اجرای چندین پاس رندرینگ جهت پنهان کردن Z-fighting است. با ارائه پشتیبانی سخت‌افزاری بومی برای عمق ممیز شناور، آن‌ها به موتورها اجازه می‌دهند صحنه‌های عظیم را در یک پاس واحد و کارآمد رندر کنند.

محققان مستقل

تحلیل و مستندسازی اثبات‌های ریاضی که به جامعه گسترده‌تر اجازه می‌دهد این تکنیک‌ها را پیاده‌سازی کنند.

محققان گرافیک و نویسندگان فنی به عنوان پلی میان ریاضیات نظری و کاربرد عملی عمل می‌کنند. چهره‌هایی مانند نیکولاس گیلموت و نویسندگان Zero Radiance و LearnOpenGL سال‌ها وقت صرف انتشار اثبات‌های کمی کرده‌اند که برای متقاعد کردن صنعت به تغییر لازم بود. تحلیل‌های آن‌ها نشان می‌دهد که افت دقت ۱/z یک نقص سخت‌افزاری نیست، بلکه یک ناهماهنگی ریاضی است که می‌تواند با هم‌راستا کردن منحنی توان ممیز شناور با فاصله فیزیکی مخروط دید، به شکلی ظریف حل شود.

معماران موتور گرافیکی 40%مهندسان سخت‌افزار 30%محققان مستقل 30%
معماران موتور گرافیکی
تمرکز بر خلوص ریاضی و ایجاد پایپ‌لاین‌های رندرینگ پیش‌فرض قدرتمندی که از آرتیفکت‌های بصری در مقیاس بزرگ جلوگیری می‌کنند.
مهندسان سخت‌افزار
اولویت دادن به استفاده بهینه از پهنای باند حافظه در عین ارائه فرمت‌های ممیز شناور ۳۲ بیتی ضروری برای رندرینگ مدرن.
محققان مستقل
تحلیل و مستندسازی اثبات‌های ریاضی که به جامعه گسترده‌تر توسعه‌دهندگان اجازه می‌دهد این تکنیک‌ها را پیاده‌سازی کنند.

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

  • تولیدکنندگان سخت‌افزار موبایل
  • تسترهای تاییدیه کنسول

منابع

پوشش منابع

8 منبع

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

معماران موتور گرافیکی 40%مهندسان سخت‌افزار 30%محققان مستقل 30%
  1. [1]Outerraمعماران موتور گرافیکی

    Maximizing Depth Buffer Range and Precision

    مطالعه در Outerra →
  2. [2]NVIDIA Technical Blogمهندسان سخت‌افزار

    Visualizing Depth Precision

    مطالعه در NVIDIA Technical Blog →
  3. [3]LearnOpenGLمحققان مستقل

    Depth testing - LearnOpenGL

    مطالعه در LearnOpenGL →
  4. [4]Godot Engineمعماران موتور گرافیکی

    Introducing Reverse Z (AKA I'm sorry for breaking your shader)

    مطالعه در Godot Engine →
  5. [5]Zero Radianceمحققان مستقل

    Quantitative Analysis of Z-Buffer Precision

    مطالعه در Zero Radiance →
  6. [6]Evergineمعماران موتور گرافیکی

    Changing to Reverse Z-Buffer

    مطالعه در Evergine →
  7. [7]nlguillemotمحققان مستقل

    Reversed-Z in OpenGL

    مطالعه در nlguillemot →
  8. [8]تیم سردبیری کوهستانمحققان مستقل

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

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

نظرات

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

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

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