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 update
    void 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 frame
    void 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 One

			CGPROGRAM

			#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. 点击运行,效果图如下所示:

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值