栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 游戏开发 > 其他

Unity PointCloud开发:Mesh渲染点云

其他 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Unity PointCloud开发:Mesh渲染点云

因任务需求,需要实现Unity中点云的渲染,同时将点云与模型相结合,达到点云在模型上特定位置的绑定。经相关探索,特此记录。


前言

在Unity中实现点云的渲染可以采用相关的插件,例如PCX插件,可以直接实现在Unity编辑器对PLY格式点云的识别,可直接拖拽到场景中并待颜色显示。但是该插件的缺点在于,相关操作需要预先在编辑器中定义,不能动态的通过脚本控制点云文件的加载与渲染。

为了实现点云在Unity程序中的动态加载与渲染,采用文件读取与Mesh渲染详解和方法。

具体实现思路为:读取点云文件中的明码信息(包括xyz和rgb),储存在C#的容器中,后期通过遍历数据,为Mesh舒服,实现渲染,过程如下。


一、点云文件数据 1.文件有效信息

点云文件的储存形式很多:PCD、PLY、XYZ、XYZRGB、CSV等等,同时文件中点云的储存格式也不尽相同。本文适用于文件中储存的点云信息为明码,如PCD的ascii编码形式或CSV格式,如下图:
PCD-ascii:

CSV:

其他格式的文件也可以进行读取,只需保证Unity在解析文件信息时能够处理掉无用信息,保留点云信息。如PCD文件,前11行信息为PCD的标准格式,可以在PCL程序中进行解析,但在本例中只需要保留点云信息即可。

因此读者在使用时可以采用文件预处理(手动将非有效信息删除)或后处理(通过程序删掉特定行数据)的形式保留有效点云信息,在此不再赘述。

2. rgb信息

如上图可见,pcd文件中的rgb值是无符号单值,U:可表示uint8,unit16,uint32,但是我们在Unity中对Mesh的颜色赋值的时候是需要得到RGB的值各是多少,因此需要进行处理:

long nrgb = long.Parse(words[3]);//获取第四列信息
long nr = (nrgb >> 16) & 0x0000ff;
long ng = (nrgb >> 8) & 0x0000ff;
long nb = (nrgb) & 0x0000ff;

Vector3 rgb = new Vector3(nr/255f, ng/255f, nb/255f);//尤其注意,将0-255的数值映射到0-1区间中
二、点云渲染

为点云数据创建Mesh:

void CreateMesh()
{
    int num = _List[0].Count;
    _PointNum = num;

    GameObject pointObj = new GameObject();
    pointObj.name = "PointCloud";

	// 绑定Mesh组件
    pointObj.AddComponent();
    pointObj.AddComponent();
    // 为点云创建新的Mesh
    Mesh meshNeed = new Mesh();
    Material mat = new Material(Shader.Find("Custom/VertexColor"));
    pointObj.GetComponent().mesh = meshNeed;
    pointObj.GetComponent().material = mat;

    Vector3[] points = new Vector3[num];
    Color[] colors = new Color[num];
    int[] indecies = new int[num];

    for (int i = 0; i < num; ++i)
    {
        points[i] = (Vector3)_List[0][i];
        indecies[i] = i;
        colors[i] = (Color)_List[1][i];
    }

    meshNeed.vertices = points;
    meshNeed.colors = colors;
    meshNeed.SetIndices(indecies, MeshTopology.Points, 0);// 设置Mesh的渲染类型为Point
}

其中Shader的代码如下:

Shader "Custom/VertexColor" {
    SubShader {
    Pass {
        LOD 200
              
                 
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
  
        struct VertexInput {
            float4 v : POSITION;
            float4 color: COLOR;
        };
         
        struct VertexOutput {
            float4 pos : SV_POSITION;
            float4 col : COLOR;
        };
         
        VertexOutput vert(VertexInput v) {
         
            VertexOutput o;
            o.pos = UnityObjectToClipPos(v.v);
            o.col = v.color;
             
            return o;
        }
         
        float4 frag(VertexOutput o) : COLOR {
            return o.col;
        }
 
        ENDCG
        } 
   }
 
}

通过以上可以实现对点云的Mesh渲染,但是存在问题:一个Mesh默认可渲染的顶点数最多为65535,可查看API ,当要渲染的点数过多时就会出现渲染一部分的问题,解决思路:

1.循环创建Mesh,一个GameObject包含多个Mesh,单个Mesh包含60000个顶点;

2.API已经说的很清楚,Mesh的索引缓冲区数据类型可更改为32位,最多支持40亿个顶点数据;

Mesh.SetIndexBufferParams(Num, UnityEngine.Rendering.IndexFormat.UInt32);

以上可实现大尺度点云数据在一个Mesh中的渲染。

三、点云数据与模型数据绑定

本人的点云数据在Unity程序外通过PCL进行处理,实现点云坐标系和模型坐标系的统一,故在Unity导入点云数据后点云与模型的关系是绑定的。

需要注意的是:PCL中点云坐标系为右手系,Unity模型坐标系为左手系,需要进行左右手的转化。

效果如下:


总结

如上实现Unity中PointCloud的Mesh渲染,欢迎批评指正。

我最大的梦想就是成为你的梦想 .HDarker

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/901838.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号