MarkDynamic()
Hints that the Mesh geometry data will be updated frequently, optimizing GPU buffer strategies for potentially faster data updates.
Read time 3 minutesLast updated 5 days ago
Definition
- Type: Method
- Namespace: UnityEngine
- Assembly: UnityEngine.CoreModule
public void MarkDynamic()
Remarks
Call this method once on a if you intend to modify its vertex or index data repeatedly and frequently.
MeshCalling sets an internal flag indicating that the mesh data is dynamic. This flag acts as a hint to the underlying graphics API (like Direct3D, Vulkan, Metal) to use a different strategy when creating the GPU buffers that store the mesh geometry. Instead of the default 'static' or 'immutable' buffers optimized for rendering meshes that don't change, Unity will request 'dynamic' buffers.
MarkDynamicBenefits of Dynamic Buffers: Updating the contents of dynamic GPU buffers is often significantly faster than updating static ones. If you are frequently calling methods like , , , , or , using dynamic buffers can reduce CPU time spent waiting for the GPU and improve overall performance.
SetVerticesSetIndicesSetVertexBufferDataSetIndexBufferDataUploadMeshDataPotential Costs and When to Use: There is a potential trade-off. Rendering performance (the GPU reading from buffers during drawing) might be slightly slower with dynamic buffers compared to static/immutable buffers, which are often placed in memory locations optimized for GPU reads. Therefore, you should only call on meshes that are actually updated frequently. Marking a mesh that rarely or never changes as dynamic might slightly decrease rendering performance without providing any update benefit.
MarkDynamicWhen to Call: It is most effective to call before you upload vertex or index data to the Mesh for the first time, or before it is first rendered. Calling also marks the mesh's data channels as dirty internally; this ensures that the next time the GPU buffers are created or updated (e.g., when data is assigned or is called), they will use the dynamic strategy. If called after buffers already exist, the effect will apply the next time the buffers are recreated.
MarkDynamicMarkDynamicUploadMeshDatausing 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); }}