zoukankan      html  css  js  c++  java
  • 初识Unity Mesh

    Mesh概念:Mesh是Unity中的一个组件,称为网格组件。通俗的讲,Mesh是指模型的网格,3D模型是由多边形拼接而成,而多边形实际上是由多个三角形拼接而成的。所以一个3D模型的表面其实是由多个彼此相连的三角面构成。三维空间中,构成这些三角形的点和边的集合就是Mesh。

    Mesh组成

    1、顶点坐标数组vertexes 

    2、顶点在uv坐标系中的位置信息数组uvs

    3、三角形顶点顺时针或者逆时针索引数组triangles

    4、MeshFiler组件,用于增加mesh属性

    5、MeshRender组件,增加材质并渲染出来。

    6、可能还需要每个顶点的法线的数组normals

    using UnityEngine;
    using UnityEditor;
    using System.Collections;
    
    public class GenMesh
    {
        [MenuItem("GameEditor/scene/Weather/GenMesh")]
        static public void GenMeshM()
        {
            Mesh m1 = CreateRect();
            AssetDatabase.CreateAsset(m1, "Assets/_Resource/model/prefab/weather/m1.asset");
        }
    
        public static Mesh CreateRect()
        {
            Mesh mesh = new Mesh();
    
            int particleNum = 10;
            //顶点坐标
            Vector3[] verts = new Vector3[4 * particleNum]; 
            //uv坐标
            Vector2[] uvs = new Vector2[4 * particleNum];
            //三角形索引
            int[] tris = new int[2 * 3 * particleNum];
    
            Vector3 position;
            for (int i = 0; i < particleNum; i++)
            {
                int i4 = i * 4;
                int i6 = i * 6;
    
                position.x = 5 * i;
                position.y = 5 * i;
                position.z = 0;
    
                //顶点坐标
                verts[i4 + 0] = position;
                verts[i4 + 1] = position + new Vector3(2, 0, 0);
                verts[i4 + 2] = position + new Vector3(2, 2, 0);
                verts[i4 + 3] = position + new Vector3(0, 2, 0);
    
                //四个顶点在UV坐标系中的位置
                uvs[i4 + 0] = new Vector2(0.0f, 0.0f);
                uvs[i4 + 1] = new Vector2(1.0f, 0.0f);
                uvs[i4 + 2] = new Vector2(1.0f, 1.0f);
                uvs[i4 + 3] = new Vector2(0.0f, 1.0f);
    
                //顺时针绘制三角形0 1 2 / 0 2 3
                tris[i6 + 0] = i4 + 0;
                tris[i6 + 1] = i4 + 1;
                tris[i6 + 2] = i4 + 2;
                tris[i6 + 3] = i4 + 0;
                tris[i6 + 4] = i4 + 2;
                tris[i6 + 5] = i4 + 3;
            }
    
            mesh.vertices = verts;
            mesh.triangles = tris;
            mesh.uv = uvs;
            mesh.RecalculateBounds();
    
            return mesh;
        }
    
        public static Mesh CreateCircle()
        {
            Mesh mesh = new Mesh();
    
            int particleNum = 10;
            Vector3[] verts = new Vector3[4 * particleNum];
            Vector2[] uvs = new Vector2[4 * particleNum];
            int[] tris = new int[2 * 3 * particleNum];
    
            Vector3 position;
            for (int i = 0; i < particleNum; i++)
            {
                int i4 = i * 4;
                int i6 = i * 6;
    
                position.x = 5 * i;
                position.y = 5 * i;
                position.z = 0;
    
                verts[i4 + 0] = position;
                verts[i4 + 1] = position + new Vector3(2, 0, 0);
                verts[i4 + 2] = position + new Vector3(2, 2, 0);
                verts[i4 + 3] = position + new Vector3(0, 2, 0);
    
                uvs[i4 + 0] = new Vector2(0.0f, 0.0f);
                uvs[i4 + 1] = new Vector2(1.0f, 0.0f);
                uvs[i4 + 2] = new Vector2(1.0f, 1.0f);
                uvs[i4 + 3] = new Vector2(0.0f, 1.0f);
    
                //顺时针绘制三角形0 1 2 / 0 2 3
                tris[i6 + 0] = i4 + 0;
                tris[i6 + 1] = i4 + 1;
                tris[i6 + 2] = i4 + 2;
                tris[i6 + 3] = i4 + 0;
                tris[i6 + 4] = i4 + 2;
                tris[i6 + 5] = i4 + 3;
            }
    
            mesh.vertices = verts;
            mesh.triangles = tris;
            mesh.uv = uvs;
            mesh.RecalculateBounds();
    
            return mesh;
        }
    }
    View Code

    代码示例生成的mesh是这个样子,未添加MeshRender,即没有材质和渲染的情况:

    添加MeshRender,即有材质和渲染的情况:

    using UnityEngine;
    using System.Collections;
    
    /*仅仅创建Mesh
     *
     *
     */
    public class CreatMesh : MonoBehaviour
    {
    
        private GameObject mMesh;
        private Material mMaterial;
    
        /*  Mesh属性
         *      长宽
         *      段数
         *      高度
         *      高度差
         */
        private Vector2 size;//长度和宽度
        private float minHeight = -10;//最小高度
        private float maxHeight = 10;//最大高度
        private Vector2 segment;//长度的段数和宽度的段数
        private float unitH;//最小高度和最大高度只差,值为正
    
        /*  顶点属性
         *      顶点
         *      uv
         *      三角形 
         */
        private Vector3[] vertexes;//顶点数
        private Vector2 uvs;//uvs坐标
        private int[] triangles;//三角形索引
    
        void Start()
        {
            creatMesh(100, 100, 3, 3, -10, 10);
        }
    
        private void creatMesh(float width, float height, uint segmentX, uint segmentY, int min, int max)
        {
            size = new Vector2(width, height);
            maxHeight = max;
            minHeight = min;
            unitH = maxHeight - minHeight;
            segment = new Vector2(segmentX, segmentY);
    
            if (mMesh != null)
            {
                Destroy(mMesh);
            }
            mMesh = new GameObject();
            mMesh.name = "CreateMesh";
    
            computeVertexes();
            DrawMesh();
        }
    
        private void computeVertexes()
        {
            int sum = Mathf.FloorToInt((segment.x + 1) * (segment.y + 1));//顶点总数
            float w = size.x / segment.x;//每一段的长度
            float h = size.y / segment.y;
    
            GetTriangles();
    
            int index = 0;
            vertexes = new Vector3[sum];
            for (int i = 0; i < segment.y + 1; i++)
            {
                for (int j = 0; j < segment.x + 1; j++)
                {
                    float tempHeight = 0;
                    vertexes[index] = new Vector3(j * w, 0, i * h);
                    index++;
                }
            }
        }
    
        private void DrawMesh()
        {
            Mesh mesh = mMesh.AddComponent<MeshFilter>().mesh;//网格
            mMesh.AddComponent<MeshRenderer>();//网格渲染器
    
            mMaterial = new Material(Shader.Find("Diffuse"));//材质
    
            mMesh.GetComponent<Renderer>().material = mMaterial;
    
            /*设置mesh*/
            mesh.Clear();//更新
            mesh.vertices = vertexes;
            //mesh.uv 
            mesh.triangles = triangles;
    
            mesh.RecalculateNormals();
            mesh.RecalculateBounds();
    
        }
    
        private int[] GetTriangles()
        {
            int sum = Mathf.FloorToInt(segment.x * segment.y * 6);//三角形顶点总数
            triangles = new int[sum];
            uint index = 0;
            for (int i = 0; i < segment.y; i++)
            {
                for (int j = 0; j < segment.x; j++)
                {
                    int role = Mathf.FloorToInt(segment.x) + 1;
                    int self = j + (i * role);
                    int next = j + ((i + 1) * role);
                    //顺时针
                    triangles[index] = self;
                    triangles[index + 1] = next + 1;
                    triangles[index + 2] = self + 1;
                    triangles[index + 3] = self;
                    triangles[index + 4] = next;
                    triangles[index + 5] = next + 1;
                    index += 6;
                }
            }
            return triangles;
        }
    }
    View Code
  • 相关阅读:
    vue 组件创建与销毁
    防止vue组件渲染不更新
    es6 includes(), startsWith(), endsWith()
    相对路径 绝对路径
    控制台打印输出
    vue2.0 $router和$route的区别
    Vue 响应式数据说明
    Linux下多线程下载工具myget
    LNMP环境简单教程
    linux下不同服务器间数据传输(wget,scp)
  • 原文地址:https://www.cnblogs.com/kane0526/p/9208865.html
Copyright © 2011-2022 走看看