当前位置:   article > 正文

Unity3d中实现点云效果_point cloud viewer and tools

point cloud viewer and tools

有一段时间没写博客了,主要是最近实在太忙,学校的毕设,论文,公司的项目,感情的事儿都加在一块儿,嗨,做男人真累啊!!!

今天跟大家分享的是个人在实现效果时的一个小技巧,希望对有相关兴趣的童鞋有所帮助,关于点云在Unity里面的实现,我在Asset Store上查了一下,还真有一个叫做Point Cloud Viewer and Tooll的插件:


Point Cloud View and Tools

当然是收费插件,看他的介绍是用DX11的特性写了shader然后才显示出点来,关于写Shader我一向都不在行,想学却一直抽不出时间,等把毕设做的差不多了再说吧。我并没有让亲们去花钱买这个插件,那也没必要写这篇博文了,下面是我们的另类的实现方案,测试了一下,30万个点有一点点的卡,不过整体效果还好。

下面介绍不适用DX11特性的实现方案:  Particle System! 就是粒子啦。。。

其实这也是受unity官方案例 Procedural Examples中一个场景的启发,用粒子发射器发射固定量的粒子,然后给每个粒子一个位置和颜色信息就OK了,开始的时候让particleEmitter.emit 为 false , 然后调用一个particleEmitter.Emit(int count)的函数,里面的count就是总共的粒子,也就是点云的点的数目了!

这是效果图:

效果图

这里可以改变粒子的position, color, size等属性,基本上满足需求。在上代码之前要说明一下的是:传统的Ellipsoid Particle Emitter 加上 Particle Renderer 才能实现上面的效果,但是有一个粒子数量的限制,好像一万多,我在拿同学一个点云文件读取的时候只是显示了很少的一部分。后来经过反复的查找才发现是其本身粒子数目有限制。 而用了新版的particle system 就没有这个限制了, 唯一觉得有点儿不足的就是它有一个lifetime的属性,就是粒子的生命周期,如果想要一直显示就必须给一个很大的值。而老版的并没有这个问题。


代码是根据官方案例改的,没有版权问题吧惊讶惊讶惊讶

  1. using UnityEngine;
  2. using System.Collections;
  3. public class HeightMapGenerator : MonoBehaviour {
  4. public Texture2D heightMap;
  5. public Material material;
  6. public Vector3 size =new Vector3(200, 30, 200);
  7. ParticleSystem.Particle[] allParticles;
  8. public Texture2D curTexture;
  9. // Use this for initialization
  10. void Start () {
  11. particleSystem.emissionRate = 0;
  12. GenerateHeightmap();
  13. }
  14. void GenerateHeightmap ()
  15. {
  16. // Create the game object containing the renderer
  17. gameObject.AddComponent<MeshFilter>();
  18. gameObject.AddComponent<MeshRenderer>();
  19. if (material)
  20. renderer.material = material;
  21. else
  22. renderer.material.color = Color.white;
  23. // Retrieve a mesh instance
  24. Mesh mesh = GetComponent<MeshFilter>().mesh;
  25. int width = Mathf.Min(heightMap.width, 255);
  26. int height = Mathf.Min(heightMap.height, 255);
  27. int y = 0;
  28. int x = 0;
  29. // Build vertices and UVs
  30. Vector3[] vertices = new Vector3[height * width];
  31. Vector2[] uv = new Vector2[height * width];
  32. Vector4[] tangents = new Vector4[height * width];
  33. Vector2 uvScale =new Vector2 (1.0f / (width - 1), 1.0f / (height - 1));
  34. Vector3 sizeScale = new Vector3 (size.x / (width - 1), size.y, size.z / (height - 1));
  35. particleSystem.Emit(height * width);
  36. allParticles = new ParticleSystem.Particle[width * height];
  37. int count = particleSystem.GetParticles(allParticles);
  38. for (y=0;y<height;y++)
  39. {
  40. for (x=0;x<width;x++)
  41. {
  42. float pixelHeight = heightMap.GetPixel(x, y).grayscale;
  43. Vector3 vertex = new Vector3 (x, pixelHeight, y);
  44. vertices[y*width + x] = Vector3.Scale(sizeScale, vertex);
  45. allParticles[y * width + x].position = Vector3.Scale(sizeScale, vertex);//点的位置
  46. allParticles[y * width + x].color = curTexture.GetPixel(x,y);//点的颜色
  47. allParticles[y * width + x].size = pixelHeight+0.6f;//点的大小
  48. uv[y*width + x] = Vector2.Scale(new Vector2 (x, y), uvScale);
  49. // Calculate tangent vector: a vector that goes from previous vertex
  50. // to next along X direction. We need tangents if we intend to
  51. // use bumpmap shaders on the mesh.
  52. Vector3 vertexL = new Vector3( x-1, heightMap.GetPixel(x-1, y).grayscale, y );
  53. Vector3 vertexR = new Vector3( x+1, heightMap.GetPixel(x+1, y).grayscale, y );
  54. Vector3 tan = Vector3.Scale( sizeScale, vertexR - vertexL ).normalized;
  55. tangents[y*width + x] =new Vector4( tan.x, tan.y, tan.z, -1.0f );
  56. }
  57. }
  58. particleSystem.SetParticles(allParticles,count);
  59. // // Assign them to the mesh
  60. // mesh.vertices = vertices;
  61. // mesh.uv = uv;
  62. //
  63. // // Build triangle indices: 3 indices into vertex array for each triangle
  64. // var triangles = new int[(height - 1) * (width - 1) * 6];
  65. // var index = 0;
  66. // for (y=0;y<height-1;y++)
  67. // {
  68. // for (x=0;x<width-1;x++)
  69. // {
  70. // // For each grid cell output two triangles
  71. // triangles[index++] = (y * width) + x;
  72. // triangles[index++] = ((y+1) * width) + x;
  73. // triangles[index++] = (y * width) + x + 1;
  74. //
  75. // triangles[index++] = ((y+1) * width) + x;
  76. // triangles[index++] = ((y+1) * width) + x + 1;
  77. // triangles[index++] = (y * width) + x + 1;
  78. // }
  79. // }
  80. // // And assign them to the mesh
  81. // mesh.triangles = triangles;
  82. //
  83. // // Auto-calculate vertex normals from the mesh
  84. // mesh.RecalculateNormals();
  85. //
  86. // // Assign tangents after recalculating normals
  87. // mesh.tangents = tangents;
  88. }
  89. }

从代码容易看出,粒子的位置是根据一张灰度图读到的,颜色是用的是另一张图。就是这样的,希望有兴趣的童鞋可以相互交流哈,

QQ: 626222539


声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/979714
推荐阅读
相关标签
  

闽ICP备14008679号