Sure - you make a single mesh - but it’s going to contain a whole lot of sets of billboards, one for each star (this is what dynamic batching / static batching is doing for you BTW, but it has limits).
BTW this is very similar to the legacy particle system’s renderer - which is why I thought that was a good idea!
If the stars are moving then you will update these billboards (quad made of two triangles) each frame, you will certainly want to rotate them to face the opposite direction to the main camera’s forward vector).
Off the top of my head the step would be:
- Decide on the number of stars - maximum for one mesh would be around 16k
- Create a mesh object
- Create an array of Vector3s for the vertices
- Create an array of Vector2s for the uvs
- Create an array of ints for the triangles
- Create the initial points (can stick them all at 0,0,0) for now -
- map the UVs of the 4 points of each quad.
- Create the six triangle entries for each quad referring to the 4 vertices
- Update the mesh
From now on you just need to modify the vertices each frame. Keep the vertices array, update it and then set it back into the mesh each frame.
Then you need to move those vertices to the stars position in the game each frame and rotate them so that they face the negative of the Camera.main.transform.forward. Basically a star would have a position but not a rotation, you could store them in a List or a Vector3.
Now the hard part - make the quad face the camera at the right position. Your meshes renderer would be set at 0,0,0 and you would have set the bounds for the mesh to be really huge so that it always renders.
For each of your stars you would move the position of the vertices. Actually a simple way of doing that is have a dummy object that you:
dummyTransform.forward = -Camera.main.transform.forward;
Before your loop setup a vertexIndex to 0 - then for each star:
dummyTransform.position = startPosition;
And then update the 4 vertices:
points[vertexIndex++] = dummyTransform.TransformPoint(topLeft);
/* Top R 1 */ points[vertexIndex++] = dummyTransform.TransformPoint(topRight);
/* Bot L 2 */ points[vertexIndex++] = dummyTransform.TransformPoint(bottomLeft);
/* Bot R 3 */ points[vertexIndex++] = dummyTransform.TransformPoint(bottomRight);
How about a particle system? Build a particle system with roughly about 300-600 motion-less particles at any given time, set the lifetime to long, do something tweaking etc. You can give this a go, it will takes just 5-10 minutes to setup a prototype.
– Chronos-LThat sounds quite similar to the mesh approach since it will also create a lot of meshes for particles.I am not sure but how would that give a better performance then the solutions above ? Don't take me wrong,im just trying to find the most optimum way to do this. So if you think particles are more optimum i would like to hear why in more depth if you can clarify ? :)
– NidreThe particle system will be a single draw call and will handle the batching better than the other automatic options.
– whydoidoitMind you - any form of transparency is a nightmare on iOS/Droid - so perhaps you'd want to use a non-transparent shader - or build your own "combined" star mesh to mean that your code only needed a single draw call. In terms of shaders: 1. Do not use a cutout shader on mobile - the fragment discard damages optimisation badly 2. Perhaps as stars are small transparent won't really mean a lot of overdraw - it depends on the order of the shaders (I guess do the stars first!) and the number of them
– whydoidoitSo if i understood you correctly you suggesting the second option with a optimized shared,am i correct ?(Btw i will share material and texture so it would be 1 draw call anyways)
– Nidre