[ Web Proxy ]
URL:
Viewing: https://docs.unity3d.com/ScriptReference/Mesh.SetVertexBufferData.html [Back]  [Original]

Unity - Scripting API: Mesh.SetVertexBufferData
Version: Unity 6.5 (6000.5)
    • Supported
    • Legacy
    LanguageEnglish
    • C#

    Mesh.SetVertexBufferData

    Suggest a change

    Success!

    Thank you for helping us improve the quality of Unity Documentation. Although we cannot accept all submissions, we do read each suggested change from our users and will make updates where applicable.

    Close

    Submission failed

    For some reason your suggested change could not be submitted. Please <a>try again</a> in a few minutes. And thank you for taking the time to help us improve the quality of Unity Documentation.

    Close
    Your name Your email Suggestion* Submit suggestion

    Cancel

    Switch to Manual

    Declaration

    public void SetVertexBufferData(NativeArray<T> data, int dataStart, int meshBufferStart, int count, int stream, MeshUpdateFlags flags);

    Declaration

    public void SetVertexBufferData(T[] data, int dataStart, int meshBufferStart, int count, int stream, MeshUpdateFlags flags);

    Declaration

    public void SetVertexBufferData(List<T> data, int dataStart, int meshBufferStart, int count, int stream, MeshUpdateFlags flags);

    Parameters

    Parameter Description
    data The source data container from which the vertex data is copied.
    dataStart The first element in the source data to copy from.
    meshBufferStart The first element in mesh vertex buffer to receive the data.
    count The number of elements of type T to copy from the data container into the Mesh buffer.
    stream The vertex buffer stream to set data for. The default is 0. The value must be within the range 0 to 3.
    flags The optional MeshUpdateFlags flags that control the update behavior of the mesh.

    Description

    Sets the data within a specific vertex buffer stream of the mesh's vertex buffer directly copied from data source.

    You can use SetVertexBufferData to set vertex data directly, without using format conversions for each vertex attribute. Elements are copied from the source container to the destination range within the mesh's vertex buffer.

    This method does not update vertex attributes or vertex layout of the Mesh. You must configure the vertex buffer structure via SetVertexBufferParams before calling this method, defining the vertex count, layout, and which vertex streams to use.

    This is a high-performance, low-level method for populating mesh vertex data. It provides direct access to the underlying vertex buffer with minimal validation or data conversion overhead, making it suitable for performance-critical scenarios where you need maximum control over mesh data.

    For simpler ways to set vertex data that handle vertex attribute configuration automatically, use SetVertices, SetNormals, SetUVs, or other attribute-specific methods instead.

    // Generates a procedural triangle mesh with custom vertex format.
    // Attach this script to a GameObject and enter Play mode.
    // Tip: Use the Rendering Debugger window to inspect vertex attributes in the Scene view.
    
    using System.Runtime.InteropServices;
    using Unity.Collections;
    using UnityEngine;
    using UnityEngine.Rendering;
    
    // A 2-component vector storing 32-bit floats as 16-bit floats.
    public readonly struct Float16x2
    {
        readonly ushort m_X, m_Y;
    
        public Float16x2(float x, float y)
        {
            m_X = Mathf.FloatToHalf(x);
            m_Y = Mathf.FloatToHalf(y);
        }
    }
    
    // A 4-component vector storing normalized floats [-1, 1] as 16-bit signed normalized values (SNorm16).
    public readonly struct SNorm16x4
    {
        readonly ushort m_X, m_Y, m_Z, m_W;
    
        public SNorm16x4(float x, float y, float z, float w)
        {
            m_X = FloatToSNorm16(x);
            m_Y = FloatToSNorm16(y);
            m_Z = FloatToSNorm16(z);
            m_W = FloatToSNorm16(w);
        }
    
        // Converts a float in range [-1, 1] to a 16-bit signed normalized representation by clamping and scaling by 32767.
        static ushort FloatToSNorm16(float v) => (ushort)(32767f * Mathf.Clamp(v, -1f, 1f));
    }
    
    [RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
    class SetVertexBufferDataExample : MonoBehaviour
    {
        // Vertex structure with sequential memory layout containing position, compressed 16-bit normal, 32-bit color, and half-precision texture coordinates
        [StructLayout(LayoutKind.Sequential)]
        struct Vertex
        {
            public Vector3 position;
            public SNorm16x4 normal;
            public Color32 color;
            public Float16x2 texCoord;
        }
    
        // Vertex layout descriptor array defining the format and component count for each vertex attribute, matching the Vertex struct 
        static readonly VertexAttributeDescriptor[] k_VertexDescriptors = new VertexAttributeDescriptor[]
        {
            new(VertexAttribute.Position, VertexAttributeFormat.Float32, 3),
            new(VertexAttribute.Normal, VertexAttributeFormat.SNorm16, 4),
            new(VertexAttribute.Color, VertexAttributeFormat.UNorm8, 4),
            new(VertexAttribute.TexCoord0, VertexAttributeFormat.Float16, 2),
        };
    
        Mesh m_Mesh;
    
        void Start()
        {
            // Create mesh with predefined bounds to avoid recalculation
            m_Mesh = new Mesh
            {
                name = "SampleMesh",
                bounds = new Bounds(Vector3.zero, Vector3.one * 2f),
            };
    
            // Create and assign triangle vertices
            using (var vertices = GenerateVertices())
            {
                // Configure vertex buffer layout and allocate space
                m_Mesh.SetVertexBufferParams(vertices.Length, k_VertexDescriptors);
    
                // Assigns the generated vertices to the mesh
                m_Mesh.SetVertexBufferData(vertices, 0, 0, vertices.Length);
            }
    
            // Create and assign triangle indices
            using (var indices = new NativeArray<uint>(new uint[] { 0, 1, 2 }, Allocator.Temp))
            {
                // Configure index buffer format and allocate space
                m_Mesh.SetIndexBufferParams(indices.Length, IndexFormat.UInt32);
    
                // Assigns the generated indices to the mesh
                m_Mesh.SetIndexBufferData(indices, 0, 0, indices.Length);
    
                // Define single sub-mesh spanning all indices
                m_Mesh.SetSubMesh(0, new SubMeshDescriptor(0, indices.Length));
            }
    
            // Assign mesh to MeshFilter & MeshRenderer
            GetComponent<MeshFilter>().sharedMesh = m_Mesh;
            GetComponent<MeshRenderer>().material = GraphicsSettings.currentRenderPipeline != null ? GraphicsSettings.currentRenderPipeline.defaultMaterial : new Material(Shader.Find("Standard"));
        }
    
        void OnDestroy() => Destroy(m_Mesh);
    
        // Creates an array with the triangle vertices
        NativeArray<Vertex> GenerateVertices()
        {
            var vertices = new NativeArray<Vertex>(3, Allocator.Temp);
            for (int i = 0; i < 3; i++)
            {
                // Create and assign the vertex with the computed position, matching normal, UVs, and position-derived color
                vertices[i] = new Vertex
                {
                    position = new Vector3(i - 1f, i % 2 * Mathf.Sqrt(2f), 0f),
                    normal = new SNorm16x4(0f, 0f, -1f, 0f),
                    texCoord = new Float16x2(i, i % 2 * Mathf.Sqrt(2f)),
                    color = new Color32(i == 0 ? byte.MaxValue : byte.MinValue, i == 1 ? byte.MaxValue : byte.MinValue, i == 2 ? byte.MaxValue : byte.MinValue, byte.MaxValue),
                };
            }
            return vertices;
        }
    }
    

    Additional resources: SetVertexBufferParams, ::SetIndexBufferData, MeshUpdateFlags.


    Web Proxy Viewer  |  New URL  |  Original Page