در چند وقت گذشته بیش از پیش با موجودیتی به نام voxel کار کرده ام و گاه گاه مطالبی راجع به آن در تویتر فارسی خودم و یا تویتر انگلیسیم به اشتراک گذاشته ام. سوالات فردی در تویتر من را بر آن داشت که کمی راجع به آن ها در یک پست توضیح دهم.
یک واکسل توضیح دهنده یک نقطه در فضای سه بعدی است. مثل پیکسل که یک نقطه در فضای دو بعدی یک تصویر را شرح می دهد، واکسل هم یک نقطه در فضای سه بعدی را شرح می دهد. معروفترین بازی که از این مفهوم استفاده می کند Minecraft است اما voxel ها لزوما نباید مربع باشند. توضیح یک واکسل می تواند شامل نرمی سطح و normal های آن نقطه از سطح و حتی مختصات UV برای texture باشد. voxel ها برای تعریف یک شکل در فضای سه بعدی مورد استفاده قرار می گیرند. برای نمایش معمولا با الگرویتمی یک سیستم بر پایه voxel را به مدلی بر پایه مش های معمول (بر پایه polygon) تبدیل می کنند و render می کنند. در واقع در یک مدل بر پایه voxel به جای تعریف یک سری polygon که شکل را تشکیل می دهند از مقدار دادن به خانه های یک grid سه بعدی استفاده می کنید. دقت کنید که این خانه ها الزاما نباید مکعب باشند.
شاید از خود بپرسید چرا باید مدل و فضا را در فضای voxel تعریف کنیم و هنگام نمایش به mesh تبدیل کنیم. voxel ها به جز بازی ها در نرم افزارهای پزشکی و ... نیز کاربرد دارند. دلایل مختلفی برای جذاب بودن voxel ها در domain های مختلف موجود است. در بازی ها اگر شما قصد داشته باشید که با کد و به شکل procedural دنیای بازی را تغییر دهید و مثلا به کاربر امکان کندن زمین یا ساختن سازه را بدهید. voxel ها کار ساخت ابزار برای کاربران را بسیار ساده می کنند و هم پیاده سازی شما بسیار ساده می شود و هم کاربران بسیار ساده با ابزارهایتان ارتباط برقرار می کنند. ساخت همه ابزارهای voxel based بر پایه مش های معمولی هم ممکن است اما این کار بسیار سخت و پیچیده می شود.
همچنین اگر شما بخواهید بر اساس یک الگوریتم دنیای خود را تولید کنید و مثلا کوه و دره و رود و ... بسازید. voxel ها از بهترین روش های برای نگهداری داده مربوط به دنیا برای تغییر ساده و تبدیل ساده به mesh هستند.
جذابیت دیگر voxel ها این است که به راحتی می توانید voxel های دورتر از دوربین را با detail کمتری برای کاربر به مش تبدیل کنید و همچنین می تواین به سادگی با داشتن یک درخت octree و ماتریس خلوت voxel ها ، تشخیص دهید با در نظر گرفتن موقعیت فعلی کاربر باید کدام بخش از دنیای واکسلی را به مش تبدیل کنید.
واکسل ها به جز این جذابیت ها دارای مشکلاتی هم هستند. اگر شما بخواهید دنیایتان را از تعداد زیادی voxel بسازید نیاز دارید که حافظه زیادی را برای voxel ها مصرف کنید و همچنین کار با آن ها در game enegine های آماده معمول دارای چالش هایی است زیرا این برنامه ها برای تولید مش و کلا محتوا در real-time بهینه نشده اند. مثلا در UE4 و Unity شما نمی توانید در thread هایی به جز thread اصلی بسیاری از کارها مثل تولید mesh مربوط به سیستم collision را انجام دهید و فقط می توانید آرایه vertex ها را در threadی دیگر بسازید و برای تبدیل آن به مش و نسبت دادنش به scene باید منتظر وقت خالی در thread اصلی بمانید و آن را بلاک کنید. همچنین واکسل ها پشتیبانی خوبی از انیمیشن اسکلتی ندارند و شما نمی توانید به راحتی یک مدل را در فضای واکسل انیمیت کنید و از آن رندر بگیرید. به روز کردن مش برای هر فریم بسیار کند است و الگوریتم های موجود دیگر هم بهینه نیستند (sub-optimal هستند).
شاید از خود بپرسید چرا باید مدل و فضا را در فضای voxel تعریف کنیم و هنگام نمایش به mesh تبدیل کنیم. voxel ها به جز بازی ها در نرم افزارهای پزشکی و ... نیز کاربرد دارند. دلایل مختلفی برای جذاب بودن voxel ها در domain های مختلف موجود است. در بازی ها اگر شما قصد داشته باشید که با کد و به شکل procedural دنیای بازی را تغییر دهید و مثلا به کاربر امکان کندن زمین یا ساختن سازه را بدهید. voxel ها کار ساخت ابزار برای کاربران را بسیار ساده می کنند و هم پیاده سازی شما بسیار ساده می شود و هم کاربران بسیار ساده با ابزارهایتان ارتباط برقرار می کنند. ساخت همه ابزارهای voxel based بر پایه مش های معمولی هم ممکن است اما این کار بسیار سخت و پیچیده می شود.
همچنین اگر شما بخواهید بر اساس یک الگوریتم دنیای خود را تولید کنید و مثلا کوه و دره و رود و ... بسازید. voxel ها از بهترین روش های برای نگهداری داده مربوط به دنیا برای تغییر ساده و تبدیل ساده به mesh هستند.
جذابیت دیگر voxel ها این است که به راحتی می توانید voxel های دورتر از دوربین را با detail کمتری برای کاربر به مش تبدیل کنید و همچنین می تواین به سادگی با داشتن یک درخت octree و ماتریس خلوت voxel ها ، تشخیص دهید با در نظر گرفتن موقعیت فعلی کاربر باید کدام بخش از دنیای واکسلی را به مش تبدیل کنید.
واکسل ها به جز این جذابیت ها دارای مشکلاتی هم هستند. اگر شما بخواهید دنیایتان را از تعداد زیادی voxel بسازید نیاز دارید که حافظه زیادی را برای voxel ها مصرف کنید و همچنین کار با آن ها در game enegine های آماده معمول دارای چالش هایی است زیرا این برنامه ها برای تولید مش و کلا محتوا در real-time بهینه نشده اند. مثلا در UE4 و Unity شما نمی توانید در thread هایی به جز thread اصلی بسیاری از کارها مثل تولید mesh مربوط به سیستم collision را انجام دهید و فقط می توانید آرایه vertex ها را در threadی دیگر بسازید و برای تبدیل آن به مش و نسبت دادنش به scene باید منتظر وقت خالی در thread اصلی بمانید و آن را بلاک کنید. همچنین واکسل ها پشتیبانی خوبی از انیمیشن اسکلتی ندارند و شما نمی توانید به راحتی یک مدل را در فضای واکسل انیمیت کنید و از آن رندر بگیرید. به روز کردن مش برای هر فریم بسیار کند است و الگوریتم های موجود دیگر هم بهینه نیستند (sub-optimal هستند).