美文网首页Unity3D
【Unity3D】绘制物体表面三角形网格

【Unity3D】绘制物体表面三角形网格

作者: LittleFatSheep | 来源:发表于2023-03-14 09:28 被阅读0次

1 仅绘制三角形网格

1)创建游戏对象

创建一个空对象,重命名为 Grid,并在其下添加需要绘制网格的对象,如下:

场景显示如下:

2)添加脚本组件

GridController.cs

using System;
using UnityEngine;

public class GridController : MonoBehaviour {

    private void Start () {
        ForAllChildren(transform, RebuildMesh);
    }

    private void RebuildMesh(Transform transform) {
        MeshFilter meshFilter = transform.GetComponent<MeshFilter>();
        if (meshFilter != null && meshFilter.mesh != null) {
            int[] indices = MakeIndices(meshFilter.mesh.triangles);
            meshFilter.mesh.SetIndices(indices, MeshTopology.Lines, 0);
        }
    }

    private int[] MakeIndices(int[] triangles) {
        int[] indices = new int[2 * triangles.Length];
        for( int i = 0; i < triangles.Length; i += 3 ) {
            for (int j = 0; j < 6; j++) {
                // 每个三角形转换为3条线段, 每个顶点使用2次, 对应的顶点序列是: 0, 1, 1, 2, 2, 0, 通式: (j + 1) % 6 / 2, j 的范围: 0 ~ 5
                indices[2 * i + j] = triangles[i + (j + 1) % 6 / 2];
            }
        }
        return indices;
    }

    private void ForAllChildren(Transform transform, Action<Transform> action) {
        action.Invoke(transform);
        for (int i = 0; i < transform.childCount; i++) {
            ForAllChildren(transform.GetChild(i), action);
        }
    }
}

说明: GridController 脚本组件挂在 Grid 对象上。

运行效果:

3)给网格添加新材质

GridController.cs

using System;
using UnityEngine;

public class GridController : MonoBehaviour {
    public Material material;

    private void Start () {
        ForAllChildren(transform, RebuildMesh);
    }

    private void RebuildMesh(Transform transform) {
        MeshFilter meshFilter = transform.GetComponent<MeshFilter>();
        MeshRenderer meshRenderer = transform.GetComponent<MeshRenderer>();
        if (meshFilter != null && meshFilter.mesh != null && meshRenderer != null) {
            meshRenderer.material = material;
            int[] indices = MakeIndices(meshFilter.mesh.triangles);
            meshFilter.mesh.SetIndices(indices, MeshTopology.Lines, 0);
        }
    }

    private int[] MakeIndices(int[] triangles) {
        int[] indices = new int[2 * triangles.Length];
        for( int i = 0; i < triangles.Length; i += 3 ) {
            for (int j = 0; j < 6; j++) {
                // 每个三角形转换为3条线段, 每个顶点使用2次, 对应的顶点序列是: 0, 1, 1, 2, 2, 0, 通式: (j + 1) % 6 / 2, j 的范围: 0 ~ 5
                indices[2 * i + j] = triangles[i + (j + 1) % 6 / 2];
            }
        }
        return indices;
    }

    private void ForAllChildren(Transform transform, Action<Transform> action) {
        action.Invoke(transform);
        for (int i = 0; i < transform.childCount; i++) {
            ForAllChildren(transform.GetChild(i), action);
        }
    }
}

运行效果:

2 绘制表面和三角形网格

场景中所有对象同第 1 节,脚本组件如下:

GridController.cs

using System;
using UnityEngine;
using UnityEngine.Rendering;

public class GridController : MonoBehaviour {
    public Material material;

    private void Start () {
        ForAllChildren(transform, RebuildMesh);
    }

    private void RebuildMesh(Transform transform) {
        MeshFilter meshFilter = transform.GetComponent<MeshFilter>();
        MeshRenderer meshRenderer = transform.GetComponent<MeshRenderer>();
        if (meshFilter != null && meshFilter.mesh != null && meshRenderer != null) {
            InitMaterials(meshRenderer);
            int[] indices = MakeIndices(meshFilter.mesh.triangles);
            InitSubMesh(meshFilter.mesh, indices, indices.Length / 3);
        }
    }

    private void InitMaterials(MeshRenderer meshRenderer) {
        Material[] materials = new Material[meshRenderer.materials.Length + 1];
        meshRenderer.materials.CopyTo(materials, 0);
        materials[materials.Length - 1] = material;
        meshRenderer.materials = materials;
    }

    private void InitSubMesh(Mesh mesh, int[] indices, int divide) {
        mesh.SetIndexBufferParams(indices.Length, IndexFormat.UInt32);
        mesh.SetIndexBufferData(indices, 0, 0, indices.Length);
        mesh.subMeshCount = 2; // 设置2个子网格
        // 第一部分绘制三角形内部
        SubMeshDescriptor subMeshDescriptor1 = new SubMeshDescriptor(0, divide, MeshTopology.Triangles);
        mesh.SetSubMesh(0, subMeshDescriptor1);
        // 第二部分绘制线段
        SubMeshDescriptor subMeshDescriptor2 = new SubMeshDescriptor(divide, indices.Length - divide, MeshTopology.Lines);
        mesh.SetSubMesh(1, subMeshDescriptor2);
    }

    private int[] MakeIndices(int[] triangles) {
        int[] indices = new int[3 * triangles.Length];
        triangles.CopyTo(indices, 0);
        for( int i = 0; i < triangles.Length; i += 3 ) {
            for (int j = 0; j < 6; j++) {
                // 每个三角形转换为3条线段, 每个顶点使用2次, 对应的顶点序列是: 0, 1, 1, 2, 2, 0, 通式: (j + 1) % 6 / 2, j 的范围: 0 ~ 5
                indices[triangles.Length + 2 * i + j] = triangles[i + (j + 1) % 6 / 2];
            }
        }
        return indices;
    }

    private void ForAllChildren(Transform transform, Action<Transform> action) {
        action.Invoke(transform);
        for (int i = 0; i < transform.childCount; i++) {
            ForAllChildren(transform.GetChild(i), action);
        }
    }
}

运行效果:

声明:本文转自【Unity3D】绘制物体表面三角形网格

相关文章

  • 基础名词解释

    1:所有的UI都是网格绘制的,2D和3D物体都是由网格绘制的,但是绘制规则不一样,Scene/Shading Mo...

  • webgl进入三维世界

    前言: 三维物体由三角形组成的,那么我们需要像前面一样逐个绘制物体的每个三角形,最终绘制整个三维物体,但是三维与二...

  • three.js(34)-网格工具

    在场景中摆放物体时,它们之间的间距到底是多少?可以借助网格工具来精确绘制。

  • 使用 GLSL 索引绘制可旋转的金字塔+纹理

    索引绘图 引绘图是一种在绘制大网格(mesh)时的一种可以高效绘图的一种方式,普通的绘制三角形需要为每个三角形在a...

  • 为Unity3D创建素材(2):模型、绑定、动画

    模型(Mesh) 在Unity3D中使用三维模型,主要依靠Mesh Filter组件载入多边形表面物体(polyg...

  • 06-什么是索引绘图

    一、什么是索引绘图? 所谓索引绘图是一种在绘制大网格(mesh)时的一种可以高效绘图的一种方式,普通的绘制三角形需...

  • 四下数学:三角形的特性

    1、 创设情境,导入新课 1、 出示图片,找出户图中的三角形。 2、 生活中有哪些物体的形状或表面是三角形? 3、...

  • OpenGLES2.0(二)实战绘制一个三角形

    这是我们绘制的第一个图形,选择三角形,点、线、三角形是OpenGL ES世界的图形基础。无论多么复杂的几何物体,在...

  • 绘制三角形,矩形,圆形

    绘制三角形 绘制矩形 绘制圆形

  • OpenGL - 网格索引

    《OpenGL ES 应用开发实践 iOS版》中第六章,关于网格索引的理解 : 使用索引来绘制三角形的话,一般都是...

网友评论

    本文标题:【Unity3D】绘制物体表面三角形网格

    本文链接:https://www.haomeiwen.com/subject/tnpohdtx.html