shader基础入门(3)(雷达图)

小知识:

unity会根据索引winding order对图像进行渲染,因此美术画面显示有误,请对渲染顺序进行检查,此渲染顺序有误会导致图形无法正常显示,主要原因是因法线翻转导致显示异常

此索引顺时针为外立面显示,逆时针为反面显示,unity默认(顺时针)会渲染正面,剔除背面(举个例子:cf卡箱子一般情况下我们能在物体内看到外面,而外面看不到里面)

首先如何绘制一个圆?

 代码如下:不可直接用

        Mesh mesh = new Mesh();
        VertexHelper vh= new VertexHelper();

        //每个角的弧度=圆的弧度/角的个数;
        float ang=(2*Mathf.PI)/n;

        //添加圆心
        vh.AddVert(new Vector3(0,1,0),Color.white,new Vector2(0.5f,0.5f));
        //循环计算其他顶点
        for (int i = 0; i < n; i++)
        {
            float x = Mathf.Sin(ang * i) * r;
            float y = Mathf.Cos(ang * i) * r;

            float uvx = (x + r) / (2 * r);
            float uvy = (y + r) / (2 * r);
            //正面
            vh.AddVert(new Vector3(x,1,y),Color.white,new Vector2(uvx,uvy));

        }

        //计算绘制(可以使用一个循环完成)
        for (int i = 0; i < n; i++)
        {
            if (i == 0)
            {
                vh.AddTriangle(0, n, 1);
            }
            else 
            {
                vh.AddTriangle(0, i, i+1);
            }
        }


        //顶点助手数据赋值
        vh.FillMesh(mesh);

        //自动计算法线
        mesh.RecalculateBounds();

        //mesh赋值给过滤器
        GetComponent<MeshFilter>().mesh = mesh;

绘制流程:

1、创建一个mesh

 Mesh mesh = new Mesh();

2、创建顶点助手

 VertexHelper vh= new VertexHelper();

3、添加圆心

4、计算其他顶点

5、计算绘制面(顺时针/逆时针)

6、 顶点助手数据赋值

      vh.FillMesh(mesh);

7、自动计算法线

        mesh.RecalculateBounds();

8、赋值给过滤器

 GetComponent<MeshFilter>().mesh = mesh;

雷达代码(原理概念基本一致):

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.UI;

public class Leida : Graphic
{
    public float[] arr;

    public override Texture mainTexture//放置绘制材质异常(丢失等)
    {
        get
        {
            if (material.mainTexture != null)
            {
                return material.mainTexture;
            }
            return s_WhiteTexture;
        }
    }

    protected override void OnPopulateMesh(VertexHelper vh)
    {
        vh.Clear();

        int n=arr.Length;
        //最小的圆3条边
        if (n>=3)
        {
            float ang=2*Mathf.PI/n;
            //计算半径 使用宽高中比较小的做直径
            Rect rect = this.rectTransform.rect;
            //高宽直径,计算半径
            float r = rect.width < rect.height ? rect.width /2: rect.height / 2;
            //找到数组中的最大Max()函数
            float max = arr.Max();
            //求出半径最大比值,保证在合理数值之内
            float p=r/max;
            //绘制
            //添加圆心
            vh.AddVert(Vector3.zero,color,new Vector2(0.5f,0.5f));
            //计算圆周点
            for (int i = 0; i < n; i++)
            {
                //由固定半径改为比例进行计算
                float x = Mathf.Sin(i * ang) * arr[i] * p;
                float y = Mathf.Cos(i * ang) * arr[i] * p;
                float uvx = (x + r) / (2*r);
                float uvy = (y + r) / (2*r);
                vh.AddVert(new Vector3(x,y,0),color,new Vector2(uvx,uvy));
                //mesh是网格数据信息,在绘制时使用,所以添加信息没有先后顺序,可添加在顶点之前
                if (i == 0)
                {
                    vh.AddTriangle(0, n, 1);
                }
                else
                {
                    vh.AddTriangle(0, i, i + 1);
                }

            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_46043095/article/details/128614226