با مجموعهها، منظم بمانید
ذخیره و طبقهبندی محتوا براساس اولویتهای شما.
شما ممکن است چند مشکل احتمالی عملکرد مرتبط با راس را از طریق استفاده از پروفایل قاب تشخیص دهید. برای مشاهده تمام فراخوان های قرعه کشی که بازی شما در یک فریم معین انجام می دهد و تعداد موارد اولیه ترسیم شده در هر تماس قرعه کشی، از پنجره فرمان ها استفاده کنید. این می تواند تقریبی از تعداد کلی رئوس ارسال شده در یک فریم را ارائه دهد.
شکل 1. نمای نمای قاب برای یک فراخوانی تک glDrawElements ، که 2718 مثلث اولیه ترسیم شده را نشان می دهد.
فشرده سازی ویژگی Vertex
یکی از مشکلات رایجی که بازی شما ممکن است با آن روبرو شود، اندازه متوسط بزرگ راس است. تعداد زیادی از رئوس ارسال شده با اندازه متوسط بالای راس منجر به پهنای باند خواندن حافظه رئوس زیادی در هنگام خواندن توسط GPU می شود.
برای مشاهده فرمت راس برای یک فراخوانی مشخص، مراحل زیر را انجام دهید:
یک فراخوان مورد علاقه قرعه کشی را انتخاب کنید.
این می تواند یک فراخوان ترسیم معمولی برای صحنه، یک فراخوانی قرعه کشی با تعداد زیادی رئوس، یک فراخوان ترسیم برای یک مدل کاراکتر پیچیده، یا نوع دیگری از فراخوانی قرعه کشی باشد.
به صفحه Pipeline بروید و برای اسمبلی ورودی روی IA کلیک کنید. این فرمت راس را برای رئوس هایی که به GPU می آیند تعریف می کند.
یک سری صفات و قالب آنها را رعایت کنید. به عنوان مثال، R32G32B32_SFLOAT یک شناور 3 جزء 32 بیتی است.
شکل 2. مجموعه ورودی برای فراخوانی قرعه کشی، با ویژگی های فشرده نشده که منجر به اندازه راس 56 بایت می شود.
اغلب، ویژگی های راس را می توان با حداقل کاهش در کیفیت مدل های ترسیم شده فشرده کرد. به ویژه توصیه می کنیم:
فشرده سازی موقعیت راس به شناورهای نیمه دقیق 16 بیتی
فشرده سازی بافت UV مختصات به یوشورت های اعداد صحیح بدون علامت 16 بیتی
فشرده سازی فضای مماس با رمزگذاری بردارهای عادی، مماس و دونرمال با استفاده از کواترنیون ها
سایر ویژگی های متفرقه نیز ممکن است برای انواع با دقت کمتر به صورت موردی در نظر گرفته شوند.
تقسیم جریان راس
همچنین میتوانید بررسی کنید که آیا جریانهای ویژگی راس بهطور مناسب تقسیم شدهاند یا خیر. در معماریهای رندر کاشیشده مانند پردازندههای گرافیکی موبایل، موقعیتهای راس ابتدا در یک گذرگاه برای ایجاد سطلهای اولیه پردازششده در هر کاشی استفاده میشوند. اگر ویژگیهای راس در یک بافر منفرد قرار بگیرند، تمام دادههای راس برای binning در حافظه پنهان خوانده میشوند، حتی اگر فقط از موقعیتهای راس استفاده شود.
برای کاهش پهنای باند حافظه خوانده شده از راس و بهبود کارایی حافظه نهان، و در نتیجه کاهش زمان صرف شده در عبور باینینگ، دادههای راس باید به دو جریان جداگانه تقسیم شوند، یکی برای موقعیتهای راس، و دیگری برای تمام ویژگیهای راس دیگر.
برای بررسی اینکه آیا ویژگی های راس به درستی تقسیم شده اند یا خیر:
یک تماس قرعه کشی مورد علاقه را انتخاب کنید و شماره تماس قرعه کشی را یادداشت کنید.
این می تواند یک فراخوان ترسیم معمولی برای صحنه، یک فراخوانی قرعه کشی با تعداد زیادی رئوس، یک فراخوان ترسیم برای یک مدل کاراکتر پیچیده، یا نوع دیگری از فراخوانی قرعه کشی باشد.
به صفحه Pipeline بروید و برای اسمبلی ورودی روی IA کلیک کنید. این فرمت راس را برای رئوس هایی که به GPU می آیند تعریف می کند.
اتصالات صفات راس خود را مشاهده کنید. معمولاً اینها ممکن است به صورت خطی افزایش یابد (0، 1، 2، 3، و غیره)، اما همیشه اینطور نیست. موقعیت راس معمولاً اولین ویژگی رأس لیست شده است.
در قسمت State ، LastDrawInfos را پیدا کنید و شماره تماس قرعه کشی منطبق را گسترش دهید. سپس، BoundVertexBuffers را برای این فراخوانی قرعه کشی گسترش دهید.
بافرهای رأس محدود شده در طول فراخوانی قرعه کشی داده شده را با شاخص هایی که با اتصالات ویژگی راس قبلی مطابقت دارند، مشاهده کنید.
اتصالات را برای ویژگی های راس فراخوانی قرعه کشی خود گسترش دهید و بافرها را گسترش دهید.
VulkanHandle را برای بافرها مشاهده کنید، که نشاندهنده حافظه زیربنایی است که دادههای راس از آن منبع میشوند. اگر s های VulkanHandle متفاوت باشند، این بدان معناست که ویژگی ها از بافرهای زیرین مختلف نشات می گیرند. اگر s های VulkanHandle یکسان باشند اما افست ها بزرگ باشند (مثلاً بزرگتر از 100)، ویژگی ها ممکن است همچنان از بافرهای فرعی متفاوتی منشأ بگیرند، اما این نیاز به بررسی بیشتر دارد.
شکل 3. مجموعه ورودی برای فراخوانی قرعه کشی، با پانل حالت در سمت راست که نشان می دهد که ویژگی ها در اتصال 0 و 1، موقعیت راس و نرمال، یک بافر زیرین را به اشتراک می گذارند.
برای جزئیات بیشتر در مورد تقسیم جریان ورتکس و نحوه حل آن در موتورهای بازی مختلف، به پست وبلاگ ما در مورد این موضوع مراجعه کنید.
محتوا و نمونه کدها در این صفحه مشمول پروانههای توصیفشده در پروانه محتوا هستند. جاوا و OpenJDK علامتهای تجاری یا علامتهای تجاری ثبتشده Oracle و/یا وابستههای آن هستند.
تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی.
[null,null,["تاریخ آخرین بهروزرسانی 2025-07-29 بهوقت ساعت هماهنگ جهانی."],[],[],null,["# Analyze vertex formats\n\nYou may diagnose a few possible vertex-related performance problems through the\nuse of frame profiling. Use the **Commands** pane to view all of the draw calls\nyour game performs in a given frame and counts of primitives drawn per draw\ncall. This can give an approximation of the overall number of vertices submitted\nin a single frame.\n**Figure 1.** Frame profiling view for a single `glDrawElements` call, showing 2,718 triangle primitives drawn\n\nVertex attribute compression\n----------------------------\n\nOne common problem your game may face is a large average vertex size. A\nlarge number of vertices submitted with a high average vertex size results in a\nlarge vertex memory read bandwidth when read by the GPU.\n\nTo observe the vertex format for a given draw call, complete the following steps:\n\n1. Select a draw call of interest.\n\n This can be a typical draw call for the scene, a draw call with a large\n number of vertices, a draw call for a complex character model, or some other\n type of draw call.\n2. Navigate to the **Pipeline** pane, and click **IA** for input assembly.\n This defines the vertex format for vertices coming into the GPU.\n\n3. Observe a series of attributes and their formats; for example,\n `R32G32B32_SFLOAT` is a 3-component 32-bit signed float.\n\n**Figure 2.**Input assembly for a draw call, with uncompressed attributes resulting in a vertex size of 56 bytes\n\nFrequently, vertex attributes can be compressed with minimal reduction in the\nquality of the models drawn. In particular, we recommend:\n\n- Compressing vertex position to half-precision 16-bit floats\n- Compressing UV texture coordinates to 16-bit unsigned integer ushorts\n- Compressing the tangent space by encoding normal, tangent, and binormal vectors using quaternions\n\nOther miscellaneous attributes may also be considered for lower-precision types\non a case-by-case basis.\n\nVertex stream splitting\n-----------------------\n\nYou can also investigate whether vertex attribute streams are appropriately\nsplit. On tiled rendering architectures such as mobile GPUs, vertex positions\nare first used in a binning pass to create bins of primitives processed in each\ntile. If vertex attributes are interleaved into a single buffer, all vertex data\nis read into cache for binning, even though only vertex positions are used.\n\nTo reduce vertex read memory bandwidth and improve cache efficiency, and thus\nreduce time spent on the binning pass, vertex data should be split into two\nseparate streams, one for vertex positions, and one for all other vertex\nattributes.\n\nTo investigate whether vertex attributes are appropriately split:\n\n1. Select a draw call of interest, and note the draw call number.\n\n This can be a typical draw call for the scene, a draw call with a large\n number of vertices, a draw call for a complex character model, or some other\n type of draw call.\n2. Navigate to the **Pipeline** pane, and click **IA** for input assembly. This\n defines the vertex format for vertices coming into the GPU.\n\n3. Observe the bindings of your vertex attributes; typically these might\n increase linearly (0, 1, 2, 3, etc.), but this is not always the case.\n Vertex position is typically the first vertex attribute listed.\n\n4. In the **State** pane, find the `LastDrawInfos` and expand the matching draw\n call number. Then, expand the `BoundVertexBuffers` for this draw call.\n\n5. Observe the vertex buffers bound during the given draw call, with indices\n matching the vertex attribute bindings from earlier.\n\n6. Expand the bindings for your draw call's vertex attributes, and expand the\n buffers.\n\n7. Observe the `VulkanHandle` for the buffers, which represent the underlying\n memory that the vertex data sources from. If the `VulkanHandle`s are\n different, this means the attributes originate from different underlying\n buffers. If the `VulkanHandle`s are the same but the offsets are large\n (for example, greater than 100), the attributes may still originate from\n different sub-buffers, but this requires further investigation.\n\n**Figure 3.**Input assembly for a draw call, with the state panel to the right showing that the attributes at binding 0 and 1, vertex position and normal, share a single underlying buffer\n\nFor more detail about vertex stream splitting and how to resolve it on various\ngame engines, see our [blog post](/agi/frame-trace/link-to-Omars-blog-post) on the subject."]]