Unity使用mesh绘制模型

2023-11-12

基本概念

首先要知道模型是如何产生的?

比如说我们在一个3*3的空间创建这样9个点(vector3)

 这9个点构成了我们模型的范围

三点成三角,三角呈面

 然后由面绘制出体

用这种方法可以绘制我们想要的图形

理论转为实践!

第一步:绘制点

先将刚才的正方体转为代码吧

可以看到我们的正方体有9个点(3*3)

所以,我们建立一个X和Y都为3的数组来包含这9个顶点

  /// <summary>
    /// 矩阵x,y位置
    /// </summary>
    public Vector3[,] Out;

    private void OnEnable()
    { Generate();
    }

    private void Generate()
    {
        Out=new Vector3[3,3];//几行?几列?
        for (int x = 0; x < 3; x++)
        {
            for (int y = 0; y < 3;y++)
            {
                Out[x, y] = new Vector3(x, y,0);
            }
         
        }
    }

 这个方法帮我们为这个数组附了值,从(0,0,0)到(2,2,0)

顶点已经构建好了.如何证明(可视化)呢?

    private void OnDrawGizmos()
    {
        Gizmos.color = Color.black;
        for (int x = 0; x < 3; x++)
        {
            for (int y = 0; y < 3;y++)
            {
                Gizmos.DrawSphere(transform.TransformPoint(Out [x,y]),0.1f);
            }
        }
    }

OnDrawGizmos api帮助我们解决这个问题

这个方法在编辑模式里也会反复执行,为我们绘制顶点(因为在编辑模式也运行,所以现在这样写不启动的话会报空)

运行!

 这9个顶点如我们所想被绘制出来了

顶点位置确认无误,我们让当前的这个cube持有这些顶点

    private void Generate()
    {   
       
        Out=new Vector3[3,3];//几行?几列?
        for (int x = 0; x < 3; x++)
        {
            for (int y = 0; y < 3;y++)
            {
                Out[x, y] = new Vector3(x, y,0);   Debug.Log(x.ToString()+y.ToString());
            }
        }
        mesh= GetComponent<MeshFilter>().mesh;
        mesh.Clear();//清理原顶点数据
        mesh.vertices = TwoD_1(Out);//赋予新的顶点数据
    }
    
    public static T[] TwoD_1<T>(T[,] obj)
    {
        T[] obj2 = new T[obj.Length];
        for (int i = 0; i < obj.Length; i++)
            obj2[i] = obj[i / obj.GetLength(1), i % obj.GetLength(1)];
        return obj2;
    }

进行到这里,我们在运行程序,发现物体已经从正方体变为正方形了(因为目前的顶点数据z轴都为0)

第二步:三点连为三角形

在上一步骤中,我们已经成功将顶点数据保存了

在这里,我们只要调用顶点数据即可

        mesh.triangles = new int[] {a,b,c};

这段代码意为绘制一个三角形,顶点为a,b,c

 

 注意:这样绘制的三角形只有一面(跑到后面就看不到了)

顺时针绘制三角形正面可见,逆时针绘制背面可见

快速知道自己的三角形正面可见或正面可见的方法是:

从第一个顶点到第三个顶点以顶点1~顶点2距离为半径顺时针画圆是否经过第二个顶点。如果经过就是正面可见,否则背面可见

如果要绘制另一面,需要将数组反转

比如【0,2,3】绘制一个正面可见的三角形,【3,2,0】绘制一个背面可见的三角形

第三步:多个三角形构建一个面

现在,我们遍历三角形将这个面铺满

 找到规律转为算法写到脚本


        int[] Triangles = new int[(3-1)*(3-1)*3*2];//根据顶点可知2x2个三角形可以铺满这个正方形
        int T_x = 0;//第一个三角形的第一个顶点坐标为0
        for (int i = 0; i < 12;)//遍历三角形
        {
            Triangles[i++] = T_x;
            Triangles[i++] = T_x + 1;
            Triangles[i++] = T_x + 3;
            T_x++;//开始构建下一个三角形
            if ((T_x+1)%3==0)//顶点不能是3的倍数,因为3在最上面一行
            { 
                T_x++;
            }
        }

       T_x = 1;
        for (int i = 12; i < 24; )
        {
         
            Triangles[i++] = T_x;
            Triangles[i++] = T_x + 3;
            Triangles[i++] = T_x + 2;
            T_x++;//开始构建下一个三角形
            if ((T_x)%3==0)//顶点不能是3的倍数,因为3在最上面一行
            { 
                T_x++;
            }
        }
        mesh.triangles = Triangles;
        

 第四步:多面成体

现在,我们已经成功做出一面,学mesh当然不只为做一面了,肯定是为了做模型

将多面拼起来就可以获得模型

现在重新改点坐标,做一个立体模型,就像这样

 

 计算每一个面所需要的三角形位置,拼接到数组就可以实现了

如果模型黑色或透明,有两种方式:

①为mesh贴uv,然后附材质球。材质球就会根据uv来渲染

uv数组的大小应该与顶点相同,他将会把每4个顶点视为一个正方形(面)

然后你就可以为面附贴图

        for (int i = 0; i < uvs.Length; i += 3)
        {
            //正常贴图
            uvs[i] = new Vector2(0, 0);
            uvs[i + 1] = new Vector2(0, 1);
            uvs[i + 2] = new Vector2(1, 1);
        }     mesh.uv = uvs;

 ②写一个shader,获取顶点和法线直接渲染,然后将shader附给材质,再贴给材质球

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Custom/NewSurfaceShader"
{
 
    Properties{
        _Color("ColorRange",Color)=(1.0,1.0,1.0,1.0)
           
        }
   SubShader{
      
      Pass{
          CGPROGRAM
          #pragma vertex vert
          #pragma fragment frag
        fixed4 _Color;


          
          struct a2v
          {
              float4 vertex : POSITION;
              float3 normal : NORMAL;
            //  float4 texcoord : TEXCOORD0;
          };
          
          struct v2f
          {
              float4 pos:SV_POSITION;
              fixed3 color: COLOR0;
          };

v2f vert(a2v v)
{
    v2f o;
    o.pos=UnityObjectToClipPos(v.vertex);
    o.color=v.normal*0.5f+fixed3(0.5,0.5,0.5);
    return o;
}
          fixed4 frag(v2f i):SV_Target{
fixed3 c=i.color;
              c*=_Color.rgb;

              return  fixed4(c,1.0);
          }
          
          ENDCG
          }
     
       
       }
}

参考文章:

(38条消息) Unity网格篇Mesh(一)_类人_猿的博客-CSDN博客_unity 网格

(38条消息) C#数组维度转换:一维数组&二维数组&三维数组相互转换_水为痕的博客-CSDN博客_c# 一维数组转二维数组

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Unity使用mesh绘制模型 的相关文章

  • STM32 串口接收中断 代码

    1 代码介绍 今天做项目 要用到串口中断接收 在网上一搜 大量代码 copy过来编译没问题 但是运行起来才发现不能产生中断 于是决定自己搞搞 用了半天的功夫 终于有结果了 2 共同讨论 代码属个人编写 自有不足之处 望大家指出 3 单片机型

随机推荐

  • 代码走查1

    线上问 和研发一起简单的从代码层面去解决问题 略low 代码走查 1 存在的问题 SQL查询 1 对于业务上没有用的字段没必要添加 比如 IsDel 在具体的业务上 删除数据是直接硬删除 直接删除了物理数据 所以 在SQL查询的时候 SQL
  • 数据分析之航空公司客户价值分析

    航空公司客户价值分析 1 挖掘背景与目标 开启了第一个数据分析的项目 针对于航空公司价值的分析 客户关系管理的关键问题是客户分类 通过客户分类 区别无价值客户 高价值客户 企业针对不同价值的客户制定优化的个性化服务方案 采取不同的营销策略
  • c语言嵌入arm指令如何编译,ARM汇编语言与嵌入式C语言混合编程————内嵌汇编.pdf...

    ARM汇编语言与嵌入式C语言混合编程 内嵌汇编 ARM C 汇编语言与嵌入式 语言混合编程 内嵌汇编 在嵌入式程序设计中 有些场合 如对具体的硬件资源进行访问 必须用汇编语言来实 C C 现 可以采用在嵌入式 语言程序中嵌入汇编语言或嵌入式
  • 可以学学Golang、(Go的优势及适合做什么

    1 关键字少 运维简单 2 原生支持高并发 GOROUTINE 协程 进程是资源分配的最小单位 线程是CPU调度的最小单位 一个线程可以有上千个协程 不是在CPU层面去调度的 是在用户空间用Golang的一个调度器去调度不同的协程 由于协程
  • 计算机基础一:IP地址与域名解析

    一 Free IP Scanner 1 是免费的局域网IP地址扫描软件 它简单地Ping每个IP地址以检查它是否还活着 2 可以扫描出某一个局域网中所有的ip地址 正在用的IP地址和没有使用的ip地址 3 可以扫描对应的网卡MAC地址 计算
  • python日常实用技能:如何用Python将图片批量从png格式转换至WebP格式

    本文来源于公众号 csdn2299 喜欢可以关注公众号 程序员学府 最近因为工作需要去研究了下png的压缩 发现转换成webp格式可以小很多 下面给大家分享利用Python将图片批量从png格式转换至WebP格式的方法 下面来一起看看 实现
  • 远程部署java web项目_JavaWeb项目的部署以及远程调试

    Linux环境下软件的安装 Linux环境下的程序的安装 更新 卸载和查看 rpm 命令 相当于windows程序的添加 卸载程序 进程程序的安装 查看 卸载 本地程序安装 rpm ivh 程序名 本地程序查看 rpm qa 本地程序卸载
  • 4分钟插入1000万条数据到mysql数据库表

    准备工作 我用到的数据库为 mysql数据库8 0版本的 使用的InnoDB存储引 创建测试表 CREATE TABLE product id int NOT NULL AUTO INCREMENT name varchar 100 DEF
  • C++读取HDF5文件

    我将博客迁到 GitHub pages 了 本文有些纰漏 请前往 pages 查看 概述 HDF5是一种跨平台存储 高维 数组的数据格式 HDF5有多种语言的绑定 其中包括C 在这里我记录了各种踩坑后如何将数据读入C 读标量 注意头文件不是
  • vscode远程连接Linux失败,提示过程试图写入的管道不存在(三种解决办法)

    vscode报错如下 一 第一种情况 原因是本地的known hosts文件记录服务器信息与现服务器的信息冲突了 导致连接失败 解决方案就是把本地的known hosts的原服务器信息全部删掉 然后重新连接 二 第二种情况 在编写配置文件c
  • SFuzz: Slice-based Fuzzing for Real-Time Operating Systems

    原文地址 SFuzz Proceedings of the 2022 ACM SIGSAC Conference on Computer and Communications Security 源码地址 NSSL SJTU SFuzz gi
  • Python面向过程编程主要知识

    摘自尚学堂的python 人工智能课程 用于复习 python是一种解释型的 面向对象的语言 python的特点 1 可读性强 易修改 2 简介 关注业务本身 生产效率高 3 面向对象 4 免费和开源 5 可移植性和跨平台 python被编
  • spring框架学习之路(一)-入门基础(1)-IOC(控制反转)&DI(依赖注入)

    前言 我就是一小白程序猴 不懂什么高新技术 只是在学习过程中把自己遇到问题或者学到的新知识记录下来 第一给自己复习用 第二小白更懂小白的苦 自己是新手所以应该更了解在刚开始学习时哪些学起来有困难 也就避开了所谓的专家盲点 给后面入坑的人一点
  • 【深度学习】使用kaggle提供的免费GPU在线训练模型

    背景 自己电脑没有GPU 只能找找网上的平台来跑模型 但是又买不起服务器 只能使用免费的平台这样子 免费的在线平台 各大计算平台免费GPU资源总结 本文要介绍的就是第三个 虽然是国外的 但是不用翻墙就可以访问 每周免费30小时使用时长 显卡
  • JAVA操作共享文件夹文件、下载、读取(windows、Linux通用)

    一 导入包 maven中央仓库https mvnrepository com artifact org samba jcifs jcifs 1 3 3
  • 在C#中??和?分别是什么意思?

    在C 中 和 分别是什么意思 1 可空类型修饰符 引用类型可以使用空引用表示一个不存在的值 而值类型通常不能表示为空 例如 string str null 是正确的 int i null 编译器就会报错 为了使值类型也可为空 就可以使用可空
  • 背完这套Java面试八股文,自动解锁面试牛逼症被动技能

    前言 国内的互联网面试 恐怕是现存的 最接近科举考试的制度 很多人对八股文都嗤之以鼻 认为无法衡量出一个程序员的真是水平 还有一部分人则是深恶痛绝 因为实在太难背了 但是国内大环境如此 互联网IT行业的求职者太多了 如果考察的是清一溜的算法
  • Weex 项目总结

    在项目中 我觉得暂时有两个地方需要总结一下 一个是weex内部的数据请求 一个是原生方法得调用 数据请求 在PC端调试的话会有跨域问题 在手机端没有跨域问题 原生方法需要原生开发者根据 Weex文档 写一个module 再暴露出一个方法给前
  • 解决springboot 项目配置文件指定端口号没生效

    方法1 指定启动端口号8022 覆盖配置文件 SpringBootApplication public class FadadaApplication public static void main String args SpringAp
  • Unity使用mesh绘制模型

    基本概念 首先要知道模型是如何产生的 比如说我们在一个3 3的空间创建这样9个点 vector3 这9个点构成了我们模型的范围 三点成三角 三角呈面 然后由面绘制出体 用这种方法可以绘制我们想要的图形 理论转为实践 第一步 绘制点 先将刚才