Mesh渲染图形及原理

一、渲染的基本条件

渲染的第一步首先需要确认图形的顶点,点构成面,面组合成图形

而unity通过三个顶点绘制出一个三角形的面,用无数个三角性的面组成对应的图形和模型

三个顶点的渲染顺序决定了面的正反,正面可以触发碰撞等,反面则没有这种效果

三个点的顺序为顺时针就是正面,逆时针就是反面

二、如何通过渲染辨认多边形的面

当用顶点组成的三角形组成对应的模型后就会发现,无法清晰的分清每个面的具体位置,这个时候

就引出另一个知识点,那就是法线,法线是区分模型不同面的线

三、给生成的模型附图片

如果没有所确认的点组成的面,那么就无法将贴图附给对应的模型

uv的作用就是通过点确定对应的面来附图片的

四、生成一个正方体

那么现在用顶点和法线画一个正方形,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CreateMesh : MonoBehaviour
{

    // Start is called before the first frame update
    void Start()
    {
        //定义一个mesh类型的变量
        Mesh mesh = new Mesh();
        //定义顶点数组
        List<Vector3> vertices = new List<Vector3>();
        vertices.Add(new Vector3(0,5,0));
        vertices.Add(new Vector3(0,5,5));
        vertices.Add(new Vector3(5,5,5));
        vertices.Add(new Vector3(5,5,0));
        vertices.Add(new Vector3(0,0,0));
        vertices.Add(new Vector3(0,0,5));
        vertices.Add(new Vector3(5,0,5));
        vertices.Add(new Vector3(5,0,0));
        //将数组赋给mesh变量
      mesh.vertices=vertices.ToArray();
        //绘制,确定绘制顺序
       mesh.triangles=new int[]
       {
           4,3,0,
           3,4,7,
           7,2,3,
           7,6,2,
           6,1,2,
           6,5,1,
           5,0,1,
           5,4,0,
           0,2,1,
           0,3,2,
           5,7,4,
           7,5,6
       };
       //自动生成法线
        mesh.RecalculateNormals();

        List<Vector2> uv=new List<Vector2>();

        uv.Add(new Vector2(0, 0));
        uv.Add(new Vector2(1, 0));
        uv.Add(new Vector2(1, 1));
        uv.Add(new Vector2(0, 1));
        uv.Add(new Vector2(0, 0));
        uv.Add(new Vector2(1, 0));
        uv.Add(new Vector2(1, 1));
        uv.Add(new Vector2(0, 1));
        mesh.uv=uv.ToArray();
        //将对应确认的mesh赋给Cube的MeshFilter的mesh
        GetComponent<MeshFilter>().mesh = mesh;
        GetComponent<MeshCollider>().sharedMesh = mesh;
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

五、通过反向取顶点生成一个从内向外的球

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SphereMesh : MonoBehaviour
{
    public Mesh sphere;
    // Start is called before the first frame update
    void Start()
    {
        //创建一个Mesh
        Mesh mesh = new Mesh();
        //创建一个Vector3的顶点的集合
        List<Vector3> vertices = new List<Vector3>();
        List<Vector3> normals = new List<Vector3>();
        List<Vector2> uvs = new List<Vector2>();
        for (int i = 0; i < sphere.vertices.Length; i++)
        {
            vertices.Add(sphere.vertices[i]);
            normals.Add(sphere.normals[i]);
            uvs.Add(sphere.uv[i]);
        }
        mesh.vertices = vertices.ToArray();
        mesh.normals = normals.ToArray();
        mesh.uv = uvs.ToArray();

        List<int> triangles = new List<int>();
        //重新画顶点顺序,每三个一次循环,将第二个的位置和第三个的位置交换
        for (int i = 0; i < sphere.triangles.Length; i+=3)
        {
            triangles.Add(sphere.triangles[i]);
            triangles.Add(sphere.triangles[i+2]);
            triangles.Add(sphere.triangles[i+1]);
        }
        mesh.triangles = triangles.ToArray();

        GetComponent<MeshFilter>().mesh = mesh; 
        GetComponent<MeshCollider>().sharedMesh = mesh;
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

 自画一个球体

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class SelfSphereMesh : MonoBehaviour
{
    //确认顶点个数
    public int n = 20;
    //半径
    public float r = 2;
    // Start is called before the first frame update
    void Start()
    {
        Mesh mesh = new Mesh();
        //定义角度
        float angle = 2 * Mathf.PI / n;
        List<Vector3> vertices= new List<Vector3>();    
        List<int> triangles= new List<int>();
        for(int i = 0; i < n/2+1; i++)
        {
            float xr = Mathf.Sin(i * angle) * r;
            float y = Mathf.Cos(i * angle) * r;
            for (int j = 0; j < n; j++)
            {
                float x= Mathf.Sin(j * angle) * xr;
                float z = Mathf.Cos(j * angle) * xr;
                vertices.Add(new Vector3(x,y,z));
                if (j==n-1)
                {
                    float x0 = Mathf.Sin(0) * xr;
                    float z0 = Mathf.Cos(0) * xr;
                    vertices.Add(new Vector3(x0, y, z0));
                }
                if (i<n/2 && j< n)
                {
                    triangles.Add(i*(n+1)+j);
                    triangles.Add(i* (n + 1) + j+1);
                    triangles.Add((i+1)* (n + 1) + j);
                    triangles.Add((i + 1) * (n + 1) + j);
                    triangles.Add(i* (n + 1) + j+1);
                    triangles.Add((i+1)* (n + 1) + j+1);
                }
            }
        }
        mesh.vertices = vertices.ToArray();
        mesh.triangles = triangles.ToArray();

        GetComponent<MeshFilter>().mesh = mesh;
        GetComponent<MeshCollider>().sharedMesh = mesh;
    }

    // Update is called once per frame
    void Update()
    {
        
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值