Mesh.MarkDynamic
Declaration
public void MarkDynamic();Описание
Подсказывает, что данные геометрии сетки будут обновляться часто, оптимизируя стратегии буферизации GPU для потенциально более быстрого обновления данных.
Вызывайте этот метод один раз в Mesh если вы собираетесь изменять данные вершины или индекса многократно и часто.
Вызов MarkDynamic устанавливает внутренний флаг, показывающий, что данные меша динамические. Этот флаг служит подсказкой нижележащему графическому API (Direct3D, Vulkan, Metal) выбрать другую стратегию при создании буферов GPU, хранящих геометрию меша. Вместо обычных «статических» или «неизменяемых» буферов, оптимизированных под отрисовку неизменных мешей, Unity запросит «динамические» буферы.
Преимущества динамических буферов:
Обновлять содержимое динамических буферов GPU обычно заметно быстрее, чем статических. Если вы часто вызываете методы вроде SetVertices, SetIndices, SetVertexBufferData, SetIndexBufferData, или UploadMeshData, использование динамических буферов может сократить CPU время ожидания GPU и повысить общую производительность.
Потенциальные затраты и когда использовать:
Здесь возможен компромисс. Производительность рендеринга (чтение GPU из буферов при отрисовке) *может* быть немного ниже с динамическими буферами по сравнению со статическими и неизменяемыми, которые часто размещаются в памяти, оптимизированной для чтения GPU. Поэтому вызывайте MarkDynamic на мешах, которые **на самом деле часто обновляются**. Пометка меши, которая редко или никогда не изменяется, как динамической может немного снизить производительность отображения без предоставления каких-либо преимуществ обновления.
Когда звонить:
Наиболее эффективно звонить MarkDynamic **до** первой загрузки данных вершины или индекса в Mesh или до первого рендеринга. Вызов MarkDynamic также помечает каналы данных сетки как внутренне грязные; это обеспечивает, что в следующий раз, когда будут созданы или обновлены буферы GPU (e.g., когда данные назначены или UploadMeshData Если они будут вызываться после того, как буферы уже существуют, эффект будет применяться при следующем воссоздании буферов.
using UnityEngine;
// Attach this script to a GameObject with a MeshFilter and MeshRenderer. [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))] public class DynamicMeshExample : MonoBehaviour { Mesh m_Mesh; Vector3[] m_BaseVertices; Vector3[] m_UpdatedVertices;
public float waveSpeed = 1.0f; public float waveHeight = 0.5f;
void Start() { m_Mesh = new Mesh(); // Call this *before* setting data if possible, especially if updating frequently. m_Mesh.MarkDynamic();
// Setup a quad m_BaseVertices = new Vector3[] { new Vector3(-1, 0, -1), new Vector3(-1, 0, 1), new Vector3( 1, 0, 1), new Vector3( 1, 0, -1) }; m_UpdatedVertices = new Vector3[m_BaseVertices.Length]; System.Array.Copy(m_BaseVertices, m_UpdatedVertices, m_BaseVertices.Length);
int[] triangles = new int[] { 0, 1, 2, // First triangle 0, 2, 3 // Second triangle };
// Assign initial data m_Mesh.vertices = m_UpdatedVertices; m_Mesh.triangles = triangles; m_Mesh.RecalculateNormals();
MeshFilter meshFilter = GetComponent<MeshFilter>(); meshFilter.mesh = m_Mesh; }
void Update() { // Simulate a wave affecting the vertices every frame. for (int i = 0; i < m_BaseVertices.Length; i++) { Vector3 baseVertex = m_BaseVertices[i]; float timeFactor = Time.time * waveSpeed; float heightOffset = Mathf.Sin(timeFactor + baseVertex.x) * waveHeight; m_UpdatedVertices[i] = new Vector3(baseVertex.x, baseVertex.y + heightOffset, baseVertex.z); }
// Update the mesh vertices. Because we called MarkDynamic(), // this update should be more efficient than if the mesh used static buffers. m_Mesh.vertices = m_UpdatedVertices; m_Mesh.RecalculateBounds(); } void OnDestroy() { if (m_Mesh != null) Destroy(m_Mesh); } }
Дополнительные ресурсы: ,vertices,, ,normals,, ,triangles,, ,UploadMeshData,.