shader基础入门(2)(VertexHelper)

news2024/11/17 9:42:56

VertexHelper(顶点帮助器/顶点辅助类/顶点助手)

官方资料版本:2019.1

使用需要继承:using UnityEngine.UI;

描述

可以帮助为 UI 生成网格的实用程序类。

此类实现 IDisposable 以帮助进行内存管理。

属性

currentIndexCount       VertexHelper获取的数量指标设置。

currentVertCount        当前的顶点缓冲。

公共方法

AddTriangle                添加一个三角形的缓冲区。

AddUIVertexQuad       在流中添加一个四边形。

AddUIVertexStream    添加自定义 UIVertex 流和相应的索引。

AddUIVertexTriangleStream        添加一个流的三角形列表。

AddVert                        添加一个顶点到流中。

Clear                            清除所有顶点的流。

Dispose                        清理分配的内存。

FillMesh                        填充给定的流数据网格。

GetUIVertexStream       从流中创建一个流的UI顶点(在三角形中)

PopulateUIVertex          用流的索引 i 中的数据填充 UIVertex。

SetUIVertex                   在给定的索引中设置一个UIVertex 

官方示例代码

using UnityEngine;
using UnityEngine.UI;

public class ExampleClass : MonoBehaviour
{
    Mesh m;

    void Start()
    {
        Color32 color32 = Color.red;
        using (var vh = new VertexHelper())
        {
            vh.AddVert(new Vector3(0, 0), color32, new Vector2(0f, 0f));
            vh.AddVert(new Vector3(0, 100), color32, new Vector2(0f, 1f));
            vh.AddVert(new Vector3(100, 100), color32, new Vector2(1f, 1f));
            vh.AddVert(new Vector3(100, 0), color32, new Vector2(1f, 0f));

            vh.AddTriangle(0, 1, 2);
            vh.AddTriangle(2, 3, 0);
            vh.FillMesh(m);
        }
    }
}

----------------------------------------------------------------------------

使用此函数绘制圆柱和圆锥?

先看圆柱:

 unity默认圆柱是由4个面组成的,其中侧面为两个面,这里展示绘制的是一个面

首先绘制顶

 在unity中认为圆的中心点为坐标(0,0),其中要在圆上取点绘制三角形,取点越多,我们绘制的三角形越圆,与球体概念一致

所以最小的圆是等边三角形

一般在进行绘制计算不会使用,这算极端数据

绘制也需要由三角形组成下图为单个三角形绘制,绘制出一个,然后分区域依次绘制,画出圆形,通过计算我们就能获得三角形三个顶点的坐标,然后通过AddVert绘制

 接着获取顶点坐标,绘制其他面

圆柱代码如下

 public int n = 16;
    public float r =3;

    // Start is called before the first frame update
    void Start()
    {
        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);
            }
        }

        //第二个面(底盖)
        //圆心+圆的周围和已经用掉的顶点,不能重复使用
        int next = 1 + 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));
        }

        //计算绘制(因为底面故逆时针绘制)
        //所有下标+next保证不再重复使用
        for (int i = 0; i < n; i++)
        {
            if (i == 0)
            {
                vh.AddTriangle(0+next, 1 + next, n + next);
            }
            else
            {
                vh.AddTriangle(0 + next, i+1 + next, i + next);
            }
        }

        //第三个面(侧面)
        next = (1 + n) * 2;
        //循环计算其他顶点
        for (int i = 0; i < n+1; i++)
        {
            float x = Mathf.Sin(ang * i) * r;
            float y = Mathf.Cos(ang * i) * r;

            //int是整数,在进行除法计算只会返回0或者1
            float uvx = (float)i / (float)n;
            if (i==n) 
            {
                x = Mathf.Sin(ang * 0) * r;
                y = Mathf.Cos(ang * 0) * r;
            }

            //下面的顶点
            vh.AddVert(new Vector3(x,-1,y),Color.white,new Vector2(uvx,0));
            //上面顶点
            vh.AddVert(new Vector3(x, 1, y), Color.white, new Vector2(uvx, 1));

        }

        //多少面绘制多少次
        //所有下标+next保证使用不重复
        //圆是顺时针绘制,为了在外侧显示,故要逆时针绘制
        for (int i = 0; i < n; i++)
        {
            vh.AddTriangle(i*2+next,(i+1)*2+1+next,i*2+1+next);
            vh.AddTriangle(i*2+next,(i+1)*2+next,(i+1)*2+1+next);
        }



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

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

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


    }

-------------------------

在此基础代码上绘制圆锥

将顶改为1个点,让顶圆半径为0

 代码如下

 public int n = 16;
    public float r = 3;

    // Start is called before the first frame update
    void Start()
    {
        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++)
        {
            //-----------这里顶的r都改为0了-------
            float x = Mathf.Sin(ang * i) * 0;
            float y = Mathf.Cos(ang * i) * 0;

            float uvx = (x) / (2 * 0);
            float uvy = (y) / (2 * 0);
            //正面
            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);
            }
        }

        //第二个面(底盖)
        //圆心+圆的周围和已经用掉的顶点,不能重复使用
        int next = 1 + 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));
        }

        //计算绘制(因为底面故逆时针绘制)
        //所有下标+next保证不再重复使用
        for (int i = 0; i < n; i++)
        {
            if (i == 0)
            {
                vh.AddTriangle(0 + next, 1 + next, n + next);
            }
            else
            {
                vh.AddTriangle(0 + next, i + 1 + next, i + next);
            }
        }

        //第三个面(侧面)
        next = (1 + n) * 2;
        //循环计算其他顶点
        for (int i = 0; i < n + 1; i++)
        {
            float x = Mathf.Sin(ang * i) * r;
            float y = Mathf.Cos(ang * i) * r;

            //int是整数,在进行除法计算只会返回0或者1
            float uvx = (float)i / (float)n;
            if (i == n)
            {
                x = Mathf.Sin(ang * 0) * r;
                y = Mathf.Cos(ang * 0) * r;
            }

            //下面的顶点
            vh.AddVert(new Vector3(x, -1, y), Color.white, new Vector2(uvx, 0));
            //上面顶点------这里改了一个参数,让它顶绘制连接到一个点形成一个圆锥形
            
            vh.AddVert(Vector3.up, Color.white, new Vector2(uvx, 1));

        }

        //多少面绘制多少次
        //所有下标+next保证使用不重复
        //圆是顺时针绘制,为了在外侧显示,故要逆时针绘制
        for (int i = 0; i < n; i++)
        {
            vh.AddTriangle(i * 2 + next, (i + 1) * 2 + 1 + next, i * 2 + 1 + next);
            vh.AddTriangle(i * 2 + next, (i + 1) * 2 + next, (i + 1) * 2 + 1 + next);
        }



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

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

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


    }

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/148739.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【vim工具的使用】

目录&#xff1a;前言一、普通/命令模式1.文件中移动 - 12.文件中移动 - 23.复制、粘贴、剪切、删除4.行内删除5.撤回6.替换7.高亮选中8.逐单词移动 - 3二、底行模式1.退出vim2.设置行号3.替换4.搜索3.不退出vim的情况下进行操作4.多文件操作三、替换模式四、插入模式总结前言 …

Python递归小练习

递归算法是常见的基础算法之一&#xff0c;阶乘、青蛙跳台、兔子算法等便是递归算法中典型的例子。 1、阶乘以6的阶乘为例&#xff0c;计算的过程如下图所示 Python代码实现如下&#xff1a; def jiecheng(n):if n 1:result 1else:result n * jiecheng(n - 1)return resul…

蓝桥杯寒假集训第九天(回文日期)

没有白走的路&#xff0c;每一步都算数&#x1f388;&#x1f388;&#x1f388; 题目描述&#xff1a; 输入一行数据&#xff0c;这个数据是从10000101到89991231&#xff0c;输出这个数据后面的第一个回文数&#xff0c;以及输出第一个ABABBABA型的回文数。 注意&#xff1…

跟着博主一起刷题:《剑指offer》(第五天)

跟着博主一起刷题 这里使用的是题库&#xff1a; https://leetcode.cn/problem-list/xb9nqhhg/?page1 目录剑指 Offer 37. 序列化二叉树剑指 Offer 38. 字符串的排列剑指 Offer 40. 最小的k个数剑指 Offer 37. 序列化二叉树 剑指 Offer 37. 序列化二叉树 序列化&#xff1a; …

windows下mmclassification安装教程

文章目录mmclassification版本0.23.1一.官方安转教程二.安装教程mmclassification版本0.23.1 一.官方安转教程 官网 二.安装教程 创建conda环境 conda create --name openmmlab python3.8 -y进入创建的环境 conda activate openmmlab安转pytorcch conda install pytorch torc…

CSS知识点精学5-定位装饰

目录 一.定位 1&#xff0e;定位的基本介绍 2.定位的基本使用 3.静态定位 4.相对定位 5.绝对定位 6.子绝父相 a.优化学成网站推荐课程卡片 b.绝对定位盒子的居中&#xff08;案例&#xff09; 8.固定定位 9.元素的层级关系 二.装饰 1.垂直对齐方式 2.光标类型 3…

计算机网络实验报告

计算机网络实验报告 文章目录计算机网络实验报告一、验证性实验ipconfig实作一实作二问题ping实作一实作二问题tracert实作一问题一问题二问题三ARP实作一实作二实作三问题DHCP实作一问题netstat实作一实作二DNS实作一实作二实作三问题cache实作二二、Wireshark 实验数据链路层…

果蔬消毒机行业市场深度监测及发展趋势预测分析

2023-2029年中国果蔬消毒机行业市场深度监测及发展趋势预测报告报告编号&#xff1a;1691217本报告著作权归博研咨询所有&#xff0c;未经书面许可&#xff0c;任何组织和个人不得以任何形式复制、传播或输出中华人民共和国境外。任何未经授权使用本报告的相关商业行为都将违反…

STP生成树基础,一个难点

技术背景&#xff1a;二层交换机网络的冗余性与环路 二层环路带来的问题&#xff08;三层环路&#xff0c;ttl跳数达到一定次数会丢弃&#xff09; 典型问题 1&#xff1a;广播风暴不停的在接口内复制转发广播 2&#xff1a;MAC地址漂移 sw1接口1与2&#xff0c;对sw3的接收ma…

CentOS7.x下部署oracle19c环境

CentOS7.x下部署oracle19c环境 文章目录CentOS7.x下部署oracle19c环境前言一、环境准备工作1.1、虚拟机搭建及关闭防火墙和selinux1.2、RPM包预安装1.3、检查安装情况用户组已创建完成1.4、创建目录1.5、修改/etc/hosts 文件1.6、设置oracle口令1.7、设置环境变量1.8、将oracle…

[LeetCode周赛复盘] 第 327 场周赛20230108

[LeetCode周赛复盘] 第 327 场周赛20230108 一、本周周赛总结二、 [Easy] 6283. 正整数和负整数的最大计数1. 题目描述2. 思路分析3. 代码实现三、[Medium] 6285. 执行 K 次操作后的最大分数1. 题目描述2. 思路分析3. 代码实现四、[Medium] 6284. 使字符串总不同字符的数目相等…

10、ThingsBoard-租户

1、租户的概念 目前,有很多的系统都是以多租户的形式来设计的,目的是为了实现数据隔离,thingsboard中也是如此。但是thingsboard把租户在抽象成了一种实体,后续还会讲解其它的实体;用官方的语言解释租户:您可以将租户视为一个单独的业务实体:它是拥有或生产设备和资产的…

Java中ThreadLocal说明

1、ThreadLocal是什么 ThreadLocal&#xff0c;即线程变量&#xff0c;是一个以ThreadLocal对象为键、任意对象为值的存储结构。 这个结构被附带在线程上&#xff0c;也就是说一个线程可以根据一个ThreadLocal对象查询到绑定在这个线程上的一个值。 ——《Java并发编程艺术》如…

GrapeCity Documents Data Viewer[GcDataViewer] Crack

GrapeCity Documents Data Viewer&#xff0c;简称GcDataViewer&#xff0c;是一个统一的基于 JavaScript 的客户端查看器&#xff0c;旨在加载和预览与数据相关的所有流行文档格式。目前&#xff0c;查看器支持 XLSX、SSJSON 和 CSV 格式。除了仅加载数据文件外&#xff0c;数…

卷径计算(厚度累计法/膜厚积分法)

卷径计算的截面积法请参看下面的文章链接: 卷径计算详解(通过卷绕的膜长和膜厚进行计算)_RXXW_Dor的博客-CSDN博客有关卷绕+张力控制可以参看专栏的系列文章,文章链接如下:变频器简单张力控制(线缆收放卷应用)_RXXW_Dor的博客-CSDN博客_收放卷应用张力控制的开闭环算法,…

“/ArcGIS/services”应用程序中的服务器错误

本文迁移自本人网易博客&#xff0c;写于2013年1月5日No Content说明: 执行当前 Web 请求期间&#xff0c;出现未处理的异常。请检查堆栈跟踪信息&#xff0c;以了解有关该错误以及代码中导致错误的出处的详细信息。 异常详细信息: System.Web.HttpException: No Content源错误…

第三章 图形初阶

我曾经多次向客户展示以数字和文字表示的、精心整理的统计分析结果&#xff0c;得到的只是客户呆滞的眼神&#xff0c;尴尬得房间里只能听到鸟语虫鸣。然而&#xff0c;当我使用图形向相同的用户展示相同的信息时&#xff0c;他们往往会兴致盎然&#xff0c;甚至豁然开朗。我经…

jQuery控制元素的显示与隐藏(三种方式对比)

hide和show hide:是$(“.类名”)或$(“#标签名”)或$(“标签名”).hide() show:是$(“.类名”)或$(“#标签名”)或$(“标签名”).show() 元素直接消失&#xff0c;没有任何动态效果 slideToggle 通过控制元素的高度来显示与隐藏&#xff0c;因此会有动画效果。slideToggle如果…

RHCE ansible 作业

1、jinjia2模板 hosts.j2&#xff0c;内容如下(主机名和ip地址使用变量)&#xff1a; Welcome to 主机名 &#xff01;&#xff08;比如servera.lab.example.com&#xff09; My ip is ip地址. 要求在所有受管主机生成文件&#xff1a;/etc/welcome.txt。 2、角色部分 根据下列…

【Java】生产者消费者模型

【Java】生产者消费者模型 0x1 前言 生产者和消费者问题是线程模型中的经典问题&#xff1a;生产者和消费者在同一时间段内共用同一个存储空间&#xff0c;生产者往存储空间中添加产品&#xff0c;消费者从存储空间中取走产品&#xff0c;当存储空间为空时&#xff0c;消费者…