Unity Mesh 生成图形(一)

目录

一、概述

二、获取顶点坐标和索引

三、绘制正方形

1.显示顶点坐标

2.顶点坐标的顺序

3.顶点排序

4.绘制最终效果

结束


一、概述

Unity 的 Mesh 是用于表示三维物体的网格数据结构。它是由一系列顶点和三角形组成的网格,用于描述物体的形状和外观。

Mesh 是由顶点、三角形和其他相关信息组成的,它用于在 Unity 中创建和渲染三维对象。顶点是网格的基本构建单元,它们定义了物体的形状,每个顶点都有三维坐标和其他可选属性,如法线、 UV 坐标和颜色。三角形则是由三个顶点组成的,它们定义了网格表面的平面,形成了物体的可见表面。

Mesh 类提供了许多方法来操作顶点和三角形,例如添加、删除、移动顶点和三角形,以及调整网格的大小和形状。这些操作可以在 Unity 编辑器中进行,也可以在代码中通过使用 Unity 的 API 来实现。

使用 Mesh 可以创建各种类型的三维对象,如静态物体、动态物体、碰撞检测对象等。在 Unity 中,Mesh 还支持各种纹理和光照技术,以便更好地渲染物体的外观和效果。

二、获取顶点坐标和索引

在讲解 Mesh 案例之前,这里先做个小案例来演示下 Unity 中模型是怎么渲染出来的,本节的主要作用就是展示 Mesh 中两个重要的知识点:顶点 和 顶点下标,即使看不明白也不要紧,后面会有更详细的案例。

在场景中新建一个 Quad

创建完成后,将 Shading Mode 的默认值由 Shaded 改为 Shaded Wireframe

场景中效果如下:

在上图方块就可以看到中间有一条斜着的线,一般情况下,这样设置只是为了看模型的顶点,没有实际的作用,还是恢复成默认值吧。

接下来新添加一个脚本 Test1,拖到 Quad 上,代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Test1 : MonoBehaviour
{void Start(){//1.获取mesh对象Mesh mesh = GetComponent<MeshFilter>().mesh;//2.获取mesh的顶点坐标数组Vector3[] vertices = mesh.vertices;for (int i = 0; i < vertices.Length; i++){Debug.Log(vertices[i]);}//3.获取mesh的索引数组int[] triangles = mesh.triangles;for (int i = 0; i < triangles.Length; i++){Debug.Log(triangles[i]);}}
}

运行后的打印:

注意这里的坐标是水平的,

将视野转到背面就会看到,背面根本没有渲染,是透明的

由于正面和背面共用这4个顶点,只要改下顶点的索引就可以让背面同样的渲染了,

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Test1 : MonoBehaviour
{void Start(){//1.获取mesh对象Mesh mesh = GetComponent<MeshFilter>().mesh;//2.获取mesh的顶点坐标数组Vector3[] vertices = mesh.vertices;for (int i = 0; i < vertices.Length; i++){Debug.Log(vertices[i]);}//3.获取mesh的索引数组int[] triangles = mesh.triangles;for (int i = 0; i < triangles.Length; i++){Debug.Log(triangles[i]);}triangles = new int[12] { 0, 3, 1, 3, 0, 2, 0, 1, 3, 3, 2, 0 };mesh.triangles = triangles;}
}

效果:

三、绘制正方形

看了上面的案例,如果是第一次接触 Mesh 肯定有很多东西不明白,比如说  triangles 这个变量,有一大堆无序的整型数字是怎么回事,为什么要这么写呢?它又有什么作用呢?

triangles = new int[12] { 0, 3, 1, 3, 0, 2, 0, 1, 3, 3, 2, 0 };

要搞明白这个问题,还是得以各种小案例来慢慢讲解这些知识点。

首先,在默认的场景中,创建一个空物体,取名为 Root,将位置坐标设置为0,并将视角调整为从上往下看(鸟瞰视角),那么在场景中就是这样的:

在这里可以看到,场景中有很多的格子,其中 1 格代表 Position 中 1 米的距离,在后面的案例中,顶点坐标的位置也是以此作为标准

创建一个脚本 Test3,将其拖到 Root 上。

1.显示顶点坐标

为了理解顶点坐标在三维空间是怎样的,下面我用四个球来表示四个顶点的位置

第一个球的位置为:0,0,0,是世界坐标的零点。

第二个球的位置为:0,1,0

第三个球的位置为:1,0,0

第四个球的位置为:1,1,0

我们分别给这四个球添加材质,颜色按照顺序为:红、绿、蓝、紫,这里可以记一下这几个颜色的顺序,因为后面会涉及到渲染的正反面问题。

这时候场景中如下:

从侧面45°视角看是这样的:

运行后在 Game  视图,最上面的两个球只显示了一半,为了让三个球显示完整,将摄像机的位置向后拉了一些,Z 轴设置为 -2,这样在 Game 视图就能将四个球显示完整了。

2.顶点坐标的顺序

由于 Unity 在一般情况下只渲染一个面,顶点坐标的顺序会影响当前平面渲染的是正面还是反面,这对理解 Mesh 是至关重要的,最好去亲自动手操作一编。

下面这个图就是一个平面顶点坐标的顺序,在 Unity 中,一个平面是由两个三角形组合而成的,左边三角形的顶点顺序为:0,1,2,右边的三角形的顶点顺序为:2,1,3,可以理解为一个顺时针的顺序进行排列的

我们先来渲染左边的三角形,那么数组可以这么写:

Vector3[] vertices = new Vector3[]
{new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 0, 0),
};

那么,它的下标应该这么写:

int[] triangles = new int[]{ 0, 1, 2 };

3.顶点排序

如果说顶点 Vector3 坐标需要按照严格的顺序进行排列,那么顶点的下标如果不按照这个顺序会有怎样的效果呢?下面就来测试吧。

首先,先安装正确的顺序来完成渲染:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Test3 : MonoBehaviour
{void Start(){GameObject obj = new GameObject();obj.name = "TestMesh";obj.transform.position = Vector3.zero;//网格渲染器MeshRenderer meshRenderer = obj.AddComponent<MeshRenderer>();meshRenderer.material = new Material(meshRenderer.material);//网格过滤器MeshFilter meshFilter = obj.AddComponent<MeshFilter>();//顶点坐标Vector3[] vertices = new Vector3[]{new Vector3(0, 0, 0), new Vector3(0, 1, 0), new Vector3(1, 0, 0),};//顶点下标顺序int[] triangles = new int[]{ 0, 1, 2 };//用列表数据创建网格 Mesh 对象Mesh mesh = new Mesh();//设置顶点mesh.SetVertices(vertices);//设置顶点索引mesh.triangles = triangles;// 自动计算法线mesh.RecalculateNormals();// 自动计算物体的整体边界mesh.RecalculateBounds();// 将mesh对象赋值给网格过滤器,就完成了meshFilter.mesh = mesh;}
}

运行:

这次按照正确的流程来渲染,结果是对的,如果将顶点下标的顺序颠倒过来,会发生什么呢?

int[] triangles = new int[]{ 2, 1, 0 };

运行:

这时,正面看不到三角形了,来看看反面

反面虽然能看到三角形,但是颜色有点暗是怎么回事?

这其实是灯光的问题,默认的全局环境光位置在正面,所以背面的光线就比较暗。

我们先关闭编辑器的运行,将灯光再复制一份

将坐标向后拉一点,为了就是让灯光照到背面

再将旋转角度设置为 150°

再次运行后,从背面也能看到和正面一样的效果了

在这里,换成 2,0,1 也能正常的渲染

int[] triangles = new int[]{ 2, 0, 1 };

效果:

继续换一个,换成 1,2,0 运行也是一样的。

int[] triangles = new int[]{ 1, 2, 0 };

运行:

虽然顺序打乱也能实现效果,但是并不推荐这么做,要想渲染一个正方形,最好是按照:0,1,2,2,1,3 这种顺序进行渲染。

4.绘制最终效果

理解了上面的知识点,下面来绘制一个正方形就简单了,代码:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Test3 : MonoBehaviour
{void Start(){GameObject obj = new GameObject();obj.name = "TestMesh";obj.transform.position = Vector3.zero;//网格渲染器MeshRenderer meshRenderer = obj.AddComponent<MeshRenderer>();meshRenderer.material = new Material(meshRenderer.material);//网格过滤器MeshFilter meshFilter = obj.AddComponent<MeshFilter>();//顶点坐标Vector3[] vertices = new Vector3[]{new Vector3(0, 0, 0),new Vector3(0, 1, 0),new Vector3(1, 0, 0),new Vector3(1, 1, 0),};//顶点下标顺序int[] triangles = new int[] { 0, 1, 2, 2, 1, 3 };//用列表数据创建网格 Mesh 对象Mesh mesh = new Mesh();//设置顶点mesh.SetVertices(vertices);//设置顶点索引mesh.triangles = triangles;// 自动计算法线mesh.RecalculateNormals();// 自动计算物体的整体边界mesh.RecalculateBounds();// 将mesh对象赋值给网格过滤器,就完成了meshFilter.mesh = mesh;Debug.Log(string.Join(",", triangles));}
}

效果:

继续将 Shading Mode --> Shaded 改为 Shaded Wireframe 

就能看到模型对应的三角形面和中间的那条斜线了,现在回到上面的第二章节看看,Quad 和 当前案例中的斜线的方向是不是不一样呢?

结束

如果这个帖子对你有所帮助,欢迎 关注 + 点赞 + 留言

end

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java8之接口默认方法

Java8之接口默认方法 一、介绍二、代码1、接口2、实现类3、测试代码4、效果 一、介绍 在Java8中&#xff0c;允许为接口方法提供一个默认的实现。必须用default修饰符标记这样一个方法。默认方法也可以调用其他方法 二、代码 1、接口 public interface PersonService {void…

python 进程、线程、协程基本使用

1、进程、线程以及协程【1】进程概念【2】线程的概念线程的生命周期进程与线程的区别 【3】协程(Coroutines) 2、多线程实现【1】threading模块【2】互斥锁【3】线程池【4】线程应用 3、多进程实现4、协程实现【1】yield与协程【2】asyncio模块【3】3.8版本【4】aiohttp 1. 并发…

EasyDarwin 、ffmpeg 音视频推流拉流;OBS视频推理软件、obs-rtspserver服务器;python读取rtsp流

参考&#xff1a;https://blog.csdn.net/N71FS1/article/details/130019563 一、EasyDarwin ffmpeg ffmpeg 推送音视频流到rtsp流服务器 EasyDarwin 作为rtsp流服务器 &#xff08;下载&#xff1a;https://www.easydarwin.org/p/easydarwin.html&#xff09;OBS 直播音视频录…

是德科技keysight N9000B 信号分析仪

181/2461/8938产品概述&#xff1a; 工程的内涵就是将各种创意有机地联系起来&#xff0c;并解决遇到的问题。 CXA 信号分析仪具有出色的实际性能&#xff0c;它是一款出类拔萃、经济高效的基本信号表征工具。 它的功能十分强大&#xff0c;为一般用途和教育行业的用户执行测试…

【Linux】体验一款开源的Linux服务器运维管理工具

今天为大家介绍一款开源的 Linux 服务器运维管理工具 - 1panel。 一、安装 根据官方那个提供的在线文档&#xff0c;这款工具的安装需要执行在线安装&#xff0c; # Redhat / CentOScurl -sSL https://resource.fit2cloud.com/1panel/package/quick_start.sh -o quick_start…

【学习心得】神经网络知识中的符号解释

这里我对我学到的神经网络知识中&#xff0c;常见的符号做一下记录和总结&#xff0c;方便自己在后面学习中复习。下图二分类识别图像识别猫为例。为了保存一张图片&#xff0c;需要三个矩阵&#xff0c;它们分别对应图片中的红、绿、蓝三种颜色通道&#xff0c;如果图片大小为…

Docker 部署 FRP 内网穿透 实现端口映射

Frp 是一个专注于内网穿透的高性能的反向代理应用&#xff0c;支持 TCP、UDP、HTTP、HTTPS 等多种协议&#xff0c;且支持 P2P 通信。可以将内网服务以安全、便捷的方式通过具有公网 IP 节点的中转暴露到公网。 官网地址&#xff1a;https://github.com/fatedier/frp 准备工作…

Linux重点思考(上)--权限/解压/定时任务/性能

Linux重点思考(上&#xff09;--权限/解压/定时任务 权限修改格式chmod使用 打包解压tar -zcvf ab.tar&#xff08;打包&#xff09;tar -xvf ab.tar -C/usr &#xff08;解压&#xff09; 系统防火墙service iptables statussystemctl status iptables区别 定时任务定时任务-c…

Map集合

1、Map集合实例化 步骤&#xff1a; 导包&#xff0c;java.util.Map包通过HashMap创建对象语法格式&#xff1a; Map<引用数据类型,引用数据类型> map new HashMap<>(); HashMap类的特点&#xff1a; HashMap是一个散列表&#xff0c;它存储的…

hadoop 高可用(HA)、HDFS HA、Yarn HA

目录 hadoop 高可用(HA) HDFS高可用 HDFS高可用架构 QJM 主备切换&#xff1a; Yarn高可用 hadoop 高可用(HA) HDFS高可用 HDFS高可用架构 QJM 主备切换&#xff1a; Yarn高可用

00、SpringBatch 4.x.x版本:简单入门

00、SpringBatch批处理 一、介绍1、什么是批处理&#xff1f;2、官网3、优势4、组织架构5、程序运行架构图 二、入门案例-H2版(内存)1、新建项目2、引入依赖3、新建HelloJob.java 三、入门案例-MySQL版1、引入依赖2、修改 application.yml3、验证 四、案例解析1、EnableBatchPr…

华为昇腾asend

昇腾Ascend C编程语言 Ascend C原生支持C/C编程规范&#xff0c;通过多层接口抽象、并行编程范式、孪生调试等技术&#xff0c;极大提高了算子的开发效率&#xff0c;帮助AI 参考文章 手把手教你在昇腾平台上搭建PyTorch训练环境 - 哔哩哔哩 (bilibili.com)https://www.bilibi…

Ubuntu20.04安装MatlabR2018a

一、安装包 安装包下载链接 提取码&#xff1a;kve2 网上相关教程很多&#xff0c;此处仅作为安装软件记录&#xff0c;方便后续软件重装&#xff0c;大家按需取用。 二、安装 1. 相关文件一览 下载并解压文件后&#xff0c;如下图所示&#xff1a; 2. 挂载镜像并安装 2…

【Go】五、流程控制

文章目录 1、if2、switch3、for4、for range5、break6、continue7、goto8、return 1、if 条件表达式左右的()是建议省略的if后面一定要有空格&#xff0c;和条件表达式分隔开来{ }一定不能省略if后面可以并列的加入变量的定义 if count : 20;count < 30 {fmt.Println(&quo…

node.js的常用命令

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

数据结构:单调栈和单调队列

文章目录 一、单调栈1.1、栈的思想1.2、单调栈1.2.1、单调栈的基本应用&#xff1a;找出数组中每个元素右侧第一个更大的元素1.2.2、单调栈的基本应用&#xff1a;找出数组中每个元素左侧第一个更大的元素1.2.3、单调栈拓展1.2.4、单调栈LeetCode题单 二、单调队列2.1、队列的思…

Linux系统中安装一些常用的插件备用

Linux系统中安装一些常用的插件备用 1.安装wget yum -y install wget 2.安装vim yum -y install vim-enhanced 3.更换yum源为国内的阿里云源&#xff08;选择&#xff09; 1、备份CentOS-Base.repo mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.…

盘点2024年最佳WordPress外贸主题推荐

WordPress是一个非常受欢迎的建站平台&#xff0c;它具有易用性&#xff0c;并提供了许多功能强大的主题和插件。如果你计划建立一个外贸独立站商城&#xff0c;选择一个适合的WordPress外贸主题至关重要。以下是一些外贸主题应具备的特点&#xff1a; 1. 欧美风格&#xff1a…

计算机网络-UDP协议——沐雨先生

实验内容 1.编写并运行UDP server 2.编写并运行UDP client 3.使用Wireshark抓取并分析UDP用户数据报 基本要求 1.了解UDP上server socket与client socket之间的通信过程 2.学会使用Java语言编写UDP socket服务程序 3.学会使用Java语言编写UDP socket客户程序 4.了解UDP…

【C语言基础】:自定义类型(一)--> 结构体

文章目录 一、内置类型与自定义类型1.1 内置类型&#xff08;基本数据类型&#xff09;1.2 自定义类型 二、结构体2.1 结构体的声明2.2 结构体变量的创建和初始化2.3 结构体的特殊声明2.4 结构体的自引用 三、结构体内存对齐3.1 对齐规则3.2 为什么存在内存对齐3.3 修改默认对齐…