Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

PointCloud Shader - Shader that renders a single pixel per vertex - Possible?

Discussion in 'Shaders' started by J450N, Nov 28, 2011.

  1. J450N

    J450N

    Joined:
    Nov 25, 2010
    Posts:
    20
    I'm a total noob at writing shaders and wanted to ask the community if they thought this was possible before wasting tons of hours of experimenting to find out it's not.

    What I'm attempting to do it render a pointcloud in Unity made up of many millions of points. Each point has an X,Y,Z position and an R,G,B color value. What I have been able to do so far is push these points into Particle Emitters and I get pretty decent performance (about 17fps at 500,000 points spread out over 30 emitters). If I want to push my point count over into the millions, I think I'm going to need to do something a bit more streamlined.

    I'm wondering it it'd be possible / feasible / advisable to do something like:

    01.] Custom shader that can render verts as 1 pixel color values based on vertex color:
    - Create a MeshFilter with Vertex array for each point in the pointcloud.
    - Apply the pointcloud's color value to the vertex color value.
    - Write some kind of shader that can render color values of each vertex (even though they are not triangulated / connected / have no faces)

    02.] Do some other sort of low-level draw function that can handle millions of points:
    - Maybe using something like the GL class in Unity API

    I'm a bit of a special case in that I have full control over platform / hardware in implementing this solution so I have the freedom to use methods that don't work everywhere. I'd be curious to know if anyone with more experience in shader writing has recommendations on which route to go, or if you'd like to discourage me from attempting this altogether.

    -Thanks
     
  2. Slin

    Slin

    Joined:
    Jun 27, 2010
    Posts:
    85
    You can use GL_POINTS as render mode if you use the GL class stuff, which will render every vertex as a point. But this means that you will have to do all the stuff every frame, which will be very slow due to all the function call overhead. Which would work is to have it all as one mesh and render it with some custom functionality as points, which just means to use the GL_POINTS as drawmode in the render call, which as far as I know is not possible with Unity without implementing it yourself. This should then perform quite okay for like 2mio vertices on modern hardware, probably even with many more, but I think that point rendering is a bit slower than triangle rendering...
     
  3. J450N

    J450N

    Joined:
    Nov 25, 2010
    Posts:
    20
    Update:

    I'm currently getting 20fps viewing 2 Million points spread out over 115 particle emitters. This is completely acceptable for the current project so I may forego reinventing the wheel for now, but if I may revisit alternate approaches later.

    I'm really amazed that Unity can handle 2 million particles as camera-facing billboard quads at such an acceptable frame-rate!
     
  4. Diarrhio

    Diarrhio

    Joined:
    Jan 21, 2012
    Posts:
    23
    Mind if I ask how you're doing this? I'm trying something similar but haven't gotten very far.

    Thanks!
     
  5. J450N

    J450N

    Joined:
    Nov 25, 2010
    Posts:
    20
    Diarrhio, My script pulls the points from an external file, originally a CSV where every row contained 6 columns (X, Y, Z, R, G, B) and pushes them into an array.

    I iterate through the array and for each row, I emit a particle at position X,Y,Z and Color R,G,B until I reach the maximum number of particles that a single emitter can emit (16,250), and then I instantiate a new copy of my emitter prefab and continue pushing the particles into the this emitter.
     
  6. Daniel_Brauer

    Daniel_Brauer

    Unity Technologies

    Joined:
    Aug 11, 2006
    Posts:
    3,355
    It might be faster if you populate an array and just set ParticleEmitter.particles, rather than emitting each one individually. I haven't tried this, though.
     
  7. Ippokratis

    Ippokratis

    Joined:
    Oct 13, 2008
    Posts:
    1,521
    Hi,
    Thanks for sharing this interesting technique.
    -Ippokratis
     
  8. shaan24

    shaan24

    Joined:
    May 27, 2013
    Posts:
    2
    It works. Tried on a point cloud with approx. 2 Million particles