Unity使用Mesh动态加载3D模型

2024-05-30 04:18

本文主要是介绍Unity使用Mesh动态加载3D模型,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Unity提供Mesh类型,允许用户动态的将顶点坐标,顶点颜色,顶点法向量,顶点UV等属性动态传输给Mesh类,在场景中绘制用户自定义的三维模型。

下面说下实现步骤:

1. 在场景中创建一个空物体,右键单击->Create Empty,命名为DynamicCubeObject。

2. 在工程中创建一个C#脚本,命名为DynamicMesh.cs,并将DynamicMesh.cs脚本拖拽到DynamicCubeObject上,DynamicMesh.cs代码如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class DynamicMesh : MonoBehaviour
{private Mesh DynamicMeshCube;private Vector3[] VertexPositions;  private Color[] VertexColors;private Vector3[] VertexNornals;private int[] Indices;// Start is called before the first frame updatevoid Start(){DynamicMeshCube = new Mesh();GameObject go = new GameObject("Dynamic_Cube");go.transform.SetParent(this.transform, false);go.transform.localScale = new Vector3(1, 1, 1);//go.transform.rotation = Quaternion.AngleAxis(0, Vector3.up);MeshFilter meshFilter = go.AddComponent<MeshFilter>();MeshRenderer meshRenderer = go.AddComponent<MeshRenderer>();meshFilter.mesh = DynamicMeshCube;meshRenderer.material = new Material(Shader.Find("Unlit/CubeShader"));}// Update is called once per framevoid Update(){}void FixedUpdate(){VertexPositions = new Vector3[36];VertexColors = new Color[36];VertexNornals = new Vector3[36];VertexPositions[0] = new Vector3(-1.0f, 1.0f, 1.0f);VertexColors[0]    = new Color(0f, 0.5273f, 0.2656f);VertexNornals[0]   = new Vector3(0.0f, 0.0f, 1.0f);VertexPositions[1] = new Vector3(-1.0f, -1.0f, 1.0f);VertexColors[1] = new Color(0f, 0.5273f, 0.2656f);VertexNornals[1] = new Vector3(0.0f, 0.0f, 1.0f);VertexPositions[2] = new Vector3(1.0f, 1.0f, 1.0f);VertexColors[2] = new Color(0f, 0.5273f, 0.2656f);VertexNornals[2] = new Vector3(0.0f, 0.0f, 1.0f);VertexPositions[3] = new Vector3(-1.0f, -1.0f, 1.0f);VertexColors[3] = new Color(0f, 0.5273f, 0.2656f);VertexNornals[3] = new Vector3(0.0f, 0.0f, 1.0f);VertexPositions[4] = new Vector3(1.0f, -1.0f, 1.0f);VertexColors[4] = new Color(0f, 0.5273f, 0.2656f);VertexNornals[4] = new Vector3(0.0f, 0.0f, 1.0f);VertexPositions[5] = new Vector3(1.0f, 1.0f, 1.0f);VertexColors[5] = new Color(0f, 0.5273f, 0.2656f);VertexNornals[5] = new Vector3(0.0f, 0.0f, 1.0f);VertexPositions[6] = new Vector3(1.0f, 1.0f, 1.0f);VertexColors[6] = new Color(0.0f, 0.3398f, 0.9023f);VertexNornals[6] = new Vector3(1.0f, 0.0f, 0.0f);VertexPositions[7] = new Vector3(1.0f, -1.0f, 1.0f);VertexColors[7] = new Color(0.0f, 0.3398f, 0.9023f);VertexNornals[7] = new Vector3(1.0f, 0.0f, 0.0f);VertexPositions[8] = new Vector3(1.0f, 1.0f, -1.0f);VertexColors[8] = new Color(0.0f, 0.3398f, 0.9023f);VertexNornals[8] = new Vector3(1.0f, 0.0f, 0.0f);VertexPositions[9] = new Vector3(1.0f, -1.0f, 1.0f);VertexColors[9] = new Color(0.0f, 0.3398f, 0.9023f);VertexNornals[9] = new Vector3(1.0f, 0.0f, 0.0f);VertexPositions[10] = new Vector3(1.0f, -1.0f, -1.0f);VertexColors[10] = new Color(0.0f, 0.3398f, 0.9023f);VertexNornals[10] = new Vector3(1.0f, 0.0f, 0.0f);VertexPositions[11] = new Vector3(1.0f, 1.0f, -1.0f);VertexColors[11] = new Color(0.0f, 0.3398f, 0.9023f);VertexNornals[11] = new Vector3(1.0f, 0.0f, 0.0f);VertexPositions[12] = new Vector3(1.0f, 1.0f, -1.0f);VertexPositions[13] = new Vector3(1.0f, -1.0f, -1.0f);VertexPositions[14] = new Vector3(-1.0f, 1.0f, -1.0f);VertexPositions[15] = new Vector3(1.0f, -1.0f, -1.0f);VertexPositions[16] = new Vector3(-1.0f, -1.0f, -1.0f);VertexPositions[17] = new Vector3(-1.0f, 1.0f, -1.0f);VertexColors[12] = new Color(0f, 0.5273f, 0.2656f);VertexColors[13] = new Color(0f, 0.5273f, 0.2656f);VertexColors[14] = new Color(0f, 0.5273f, 0.2656f);VertexColors[15] = new Color(0f, 0.5273f, 0.2656f);VertexColors[16] = new Color(0f, 0.5273f, 0.2656f);VertexColors[17] = new Color(0f, 0.5273f, 0.2656f);VertexNornals[12] = new Vector3(0.0f, 0.0f, -1.0f);VertexNornals[13] = new Vector3(0.0f, 0.0f, -1.0f);VertexNornals[14] = new Vector3(0.0f, 0.0f, -1.0f);VertexNornals[15] = new Vector3(0.0f, 0.0f, -1.0f);VertexNornals[16] = new Vector3(0.0f, 0.0f, -1.0f);VertexNornals[17] = new Vector3(0.0f, 0.0f, -1.0f);VertexPositions[18] = new Vector3(-1.0f, 1.0f, -1.0f);VertexPositions[19] = new Vector3(-1.0f, -1.0f, -1.0f);VertexPositions[20] = new Vector3(-1.0f, 1.0f, 1.0f);VertexPositions[21] = new Vector3(-1.0f, -1.0f, -1.0f);VertexPositions[22] = new Vector3(-1.0f, -1.0f, 1.0f);VertexPositions[23] = new Vector3(-1.0f, 1.0f, 1.0f);VertexColors[18] = new Color(0.0f, 0.3398f, 0.9023f);VertexColors[19] = new Color(0.0f, 0.3398f, 0.9023f);VertexColors[20] = new Color(0.0f, 0.3398f, 0.9023f);VertexColors[21] = new Color(0.0f, 0.3398f, 0.9023f);VertexColors[22] = new Color(0.0f, 0.3398f, 0.9023f);VertexColors[23] = new Color(0.0f, 0.3398f, 0.9023f);VertexNornals[18] = new Vector3(-1.0f, 0.0f, 0.0f);VertexNornals[19] = new Vector3(-1.0f, 0.0f, 0.0f);VertexNornals[20] = new Vector3(-1.0f, 0.0f, 0.0f);VertexNornals[21] = new Vector3(-1.0f, 0.0f, 0.0f);VertexNornals[22] = new Vector3(-1.0f, 0.0f, 0.0f);VertexNornals[23] = new Vector3(-1.0f, 0.0f, 0.0f);VertexPositions[24] = new Vector3(-1.0f, 1.0f, -1.0f);VertexPositions[25] = new Vector3(-1.0f, 1.0f, 1.0f);VertexPositions[26] = new Vector3(1.0f, 1.0f, -1.0f);VertexPositions[27] = new Vector3(-1.0f, 1.0f, 1.0f);VertexPositions[28] = new Vector3(1.0f, 1.0f, 1.0f);VertexPositions[29] = new Vector3(1.0f, 1.0f, -1.0f);VertexColors[24] = new Color(0.8359375f,  0.17578125f,  0.125f);VertexColors[25] = new Color(0.8359375f,  0.17578125f,  0.125f);VertexColors[26] = new Color(0.8359375f,  0.17578125f,  0.125f);VertexColors[27] = new Color(0.8359375f,  0.17578125f,  0.125f);VertexColors[28] = new Color(0.8359375f,  0.17578125f,  0.125f);VertexColors[29] = new Color(0.8359375f,  0.17578125f,  0.125f);VertexNornals[24] = new Vector3(0.0f, 1.0f, 0.0f);VertexNornals[25] = new Vector3(0.0f, 1.0f, 0.0f);VertexNornals[26] = new Vector3(0.0f, 1.0f, 0.0f);VertexNornals[27] = new Vector3(0.0f, 1.0f, 0.0f);VertexNornals[28] = new Vector3(0.0f, 1.0f, 0.0f);VertexNornals[29] = new Vector3(0.0f, 1.0f, 0.0f);VertexPositions[30] = new Vector3(1.0f, -1.0f, -1.0f);VertexPositions[31] = new Vector3(1.0f, -1.0f, 1.0f);VertexPositions[32] = new Vector3(-1.0f, -1.0f, -1.0f);VertexPositions[33] = new Vector3(1.0f, -1.0f, 1.0f);VertexPositions[34] = new Vector3(-1.0f, -1.0f, 1.0f);VertexPositions[35] = new Vector3(-1.0f, -1.0f, -1.0f);VertexColors[30] = new Color(0.8359375f, 0.17578125f, 0.125f);VertexColors[31] = new Color(0.8359375f, 0.17578125f, 0.125f);VertexColors[32] = new Color(0.8359375f, 0.17578125f, 0.125f);VertexColors[33] = new Color(0.8359375f, 0.17578125f, 0.125f);VertexColors[34] = new Color(0.8359375f, 0.17578125f, 0.125f);VertexColors[35] = new Color(0.8359375f, 0.17578125f, 0.125f);VertexNornals[30] = new Vector3(0.0f, -1.0f, 0.0f);VertexNornals[31] = new Vector3(0.0f, -1.0f, 0.0f);VertexNornals[32] = new Vector3(0.0f, -1.0f, 0.0f);VertexNornals[33] = new Vector3(0.0f, -1.0f, 0.0f);VertexNornals[34] = new Vector3(0.0f, -1.0f, 0.0f);VertexNornals[35] = new Vector3(0.0f, -1.0f, 0.0f);Indices = new int[36];for (int i = 0; i < 36; i++){Indices[i] = i;}DynamicMeshCube.Clear();DynamicMeshCube.SetVertices(VertexPositions);DynamicMeshCube.SetIndices(Indices, MeshTopology.Triangles, 0);DynamicMeshCube.SetColors(VertexColors);DynamicMeshCube.SetNormals(VertexNornals);this.transform.Rotate(Vector3.right, 45 * Time.deltaTime, Space.Self);this.transform.Rotate(Vector3.up, 45 * Time.deltaTime, Space.Self);}
}

如上代码所示,实现的是一个简单的Cube,当然也可以从fbx,obj等模型文件中解析出顶点拓扑信息,传输给mesh。在上面的示例为了方便展示使用的顶点颜色而不是顶点的UV,所以还需要一个自制的Shader才能正常显示。

3. 创建目录Assets->Resources,在Resources目录下新建CubeShader.shader,DynamicMesh.cs会在代码中动态加载CubeShader.shader,CubeShader.shader代码如下:

Shader "Unlit/CubeShader"
{Properties{_Color("Color Tint", Color) = (1, 1, 1, 1)_MainTex("Main Tex", 2D) = "white" {}_BumpMap("Normal Map", 2D) = "bump" {}}SubShader{Tags { "RenderType" = "Opaque" "Queue" = "Geometry"}Pass {Tags { "LightMode" = "ForwardBase" }CGPROGRAM#pragma multi_compile_fwdbase#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"#include "AutoLight.cginc"fixed4 _Color;sampler2D _MainTex;float4 _MainTex_ST;sampler2D _BumpMap;float4 _BumpMap_ST;struct a2v {float4 vertex : POSITION;float3 normal : NORMAL;float4 tangent : TANGENT;float4 texcoord : TEXCOORD0;fixed4 color : COLOR0;};struct v2f {float4 pos : SV_POSITION;float4 uv : TEXCOORD0;float4 TtoW0 : TEXCOORD1;float4 TtoW1 : TEXCOORD2;float4 TtoW2 : TEXCOORD3;fixed4 color : COLOR0;SHADOW_COORDS(4)};v2f vert(a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;o.uv.zw = v.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;o.color = v.color;float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w;o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);TRANSFER_SHADOW(o);return o;}fixed4 frag(v2f i) : SV_Target {float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w);fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));fixed3 bump = UnpackNormal(tex2D(_BumpMap, i.uv.zw));bump = normalize(half3(dot(i.TtoW0.xyz, bump), dot(i.TtoW1.xyz, bump), dot(i.TtoW2.xyz, bump)));fixed3 albedo = i.color.rgb * _Color.rgb;fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(bump, lightDir));UNITY_LIGHT_ATTENUATION(atten, i, worldPos);return fixed4(ambient + diffuse * atten, 1.0);}ENDCG}Pass {Tags { "LightMode" = "ForwardAdd" }Blend One OneCGPROGRAM#pragma multi_compile_fwdadd// Use the line below to add shadows for point and spot lights//#pragma multi_compile_fwdadd_fullshadows#pragma vertex vert#pragma fragment frag#include "Lighting.cginc"#include "AutoLight.cginc"fixed4 _Color;sampler2D _MainTex;float4 _MainTex_ST;sampler2D _BumpMap;float4 _BumpMap_ST;struct a2v {float4 vertex : POSITION;float3 normal : NORMAL;float4 tangent : TANGENT;float4 texcoord : TEXCOORD0;fixed4 color : COLOR0;};struct v2f {float4 pos : SV_POSITION;float4 uv : TEXCOORD0;float4 TtoW0 : TEXCOORD1;float4 TtoW1 : TEXCOORD2;float4 TtoW2 : TEXCOORD3;fixed4 color : COLOR0;SHADOW_COORDS(4)};v2f vert(a2v v) {v2f o;o.pos = UnityObjectToClipPos(v.vertex);o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;o.uv.zw = v.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;o.color = v.color;float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w;o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);TRANSFER_SHADOW(o);return o;}fixed4 frag(v2f i) : SV_Target {float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w);fixed3 lightDir = normalize(UnityWorldSpaceLightDir(worldPos));fixed3 viewDir = normalize(UnityWorldSpaceViewDir(worldPos));fixed3 bump = UnpackNormal(tex2D(_BumpMap, i.uv.zw));bump = normalize(half3(dot(i.TtoW0.xyz, bump), dot(i.TtoW1.xyz, bump), dot(i.TtoW2.xyz, bump)));fixed3 albedo = i.color.rgb * _Color.rgb;fixed3 diffuse = _LightColor0.rgb * albedo * max(0, dot(bump, lightDir));UNITY_LIGHT_ATTENUATION(atten, i, worldPos);return fixed4(diffuse * atten, 1.0);}ENDCG}}FallBack "Diffuse"
}

4. 点击运行,效果图如下所示:

这篇关于Unity使用Mesh动态加载3D模型的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1015556

相关文章

大模型研发全揭秘:客服工单数据标注的完整攻略

在人工智能(AI)领域,数据标注是模型训练过程中至关重要的一步。无论你是新手还是有经验的从业者,掌握数据标注的技术细节和常见问题的解决方案都能为你的AI项目增添不少价值。在电信运营商的客服系统中,工单数据是客户问题和解决方案的重要记录。通过对这些工单数据进行有效标注,不仅能够帮助提升客服自动化系统的智能化水平,还能优化客户服务流程,提高客户满意度。本文将详细介绍如何在电信运营商客服工单的背景下进行

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

无人叉车3d激光slam多房间建图定位异常处理方案-墙体画线地图切分方案

墙体画线地图切分方案 针对问题:墙体两侧特征混淆误匹配,导致建图和定位偏差,表现为过门跳变、外月台走歪等 ·解决思路:预期的根治方案IGICP需要较长时间完成上线,先使用切分地图的工程化方案,即墙体两侧切分为不同地图,在某一侧只使用该侧地图进行定位 方案思路 切分原理:切分地图基于关键帧位置,而非点云。 理论基础:光照是直线的,一帧点云必定只能照射到墙的一侧,无法同时照到两侧实践考虑:关

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

Andrej Karpathy最新采访:认知核心模型10亿参数就够了,AI会打破教育不公的僵局

夕小瑶科技说 原创  作者 | 海野 AI圈子的红人,AI大神Andrej Karpathy,曾是OpenAI联合创始人之一,特斯拉AI总监。上一次的动态是官宣创办一家名为 Eureka Labs 的人工智能+教育公司 ,宣布将长期致力于AI原生教育。 近日,Andrej Karpathy接受了No Priors(投资博客)的采访,与硅谷知名投资人 Sara Guo 和 Elad G

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表