- Home /
How to Display Hundreds of Thousands of Sprites?
I can manage and manipulate my entities just fine with custom classes, the only current problem is rendering them. I have multiple large entities made of tiles which can rotate independently of each other, and the tiles need to change constantly. How can I render these sprites? Unity can barely handle 10k sprites, I need 100k minimum.
Um, I don't really know sadly, but I thought I'd throw out an idea anyway. What if you used a particle system and had a script manipulate the particles ins$$anonymous$$d to kind of act like your entities?
I've seen that idea before, but I also need $$anonymous$$ip$$anonymous$$aps and to be able to manipulate individual tiles regularly independent of each other which I'm not sure I can do with particle systems. I don't have much experience with them though so I'm not sure.
There must be an alternative to what you're about to do.
An alternative to rendering 100k sprites? That's what I'm here asking.
Answer by madks13 · Jul 31, 2018 at 09:13 AM
Depends on what you actually use those for.
If it's interactible tiles, with colliders or some other CPU heavy components, you can't in a normal way. Unity forces the scene manipulation to be mono threaded, which severly limits the possibiilities.
You can try looking at Unity ECS which helps manipulation of thousands of objects. But it is in beta stage and not fully ready for production.
If you simply need to display them, as suggested by Stratosome, use particles.
I only need to display them, the rest of it is a separate problem that I've mostly solved. So for the particle approach, to see if I'm on the right track here. Say I have a 256x256 grid object, I would make a particle system, set the life to infinite, speed to zero, etc. Then I'd emit 65,536 particles, then use GetParticles and loop through them and place them into their respective grid locations, assign each one the appropriate Texture2D, (or would I need to create a sprite with the Texture2D first?) Then I'd use SetParticles to apply it, and until anything changed, I'd have a square made up of tiles?
Then, since the tiles need to be updated regularly and independently of each other, I'd keep references to those particles (Can you do that?) And change the particles Texture2D/Sprite as needed. But how do I apply the changes, would I have to use SetParticles every time a single square changed? If I'm calling SetParticles for 65k particles per entity on screen, how much of a performance impact will that have? Also, what about $$anonymous$$ip$$anonymous$$aps? Will those have to be created and displayed manually?
To be honest, i haven't used that method...yet. But i have seen some videos using it while searching for information. Also, you said they need to change constantly, so i assumed you meant all at once, not separately. I'm not sure particles allow that, unless you are using some very peculiar custom shader or something similar. That said, i think in your case, ECS is the better choice for you. $$anonymous$$eshInstancedRenderer seem to be the perfect fit for what you want. I suggest you take a look at GravityDemo from Unity samples. It does instantiate around 100k cubes and manipulates them one at a time. You can find the informations about it here
I think you're right, that looks like what I need. I've done very little in Unity 3d, but for 2d, I'd use the same methods, but just draw planes and then somehow get my Texture2D's on them? I haven't had a chance to actually go through any of it, but just based on the video of the demo and description of Graphics.Draw$$anonymous$$eshInstanced I'm pretty sure that's the direction I should take it.
Answer by Arycama · Aug 01, 2018 at 01:05 PM
What are you trying to draw that requires 100,000 sprites?
Drawing a single mesh with 100,000 faces is definitely possible. However, drawing 100,000 meshes with one face each is not. (This is how sprites are rendered) This is not an issue with Unity, this is how graphics cards are designed.
Depending on how many unique textures you need, you can store them all in a texture-atlas or texture-array, and then use a special shader to render a single mesh with 100,000 quads or more.
Actually Unity's meshes have a limit of 65k vertices, so it's not possible in most cases. Only when using mesh melting can you have some cases in which you can display so many faces. But this has a workaround : using chunks. Divide the 100k faces in manageable chunks.
The reason i haven't suggested this is because it's used for procedural generation mainly and i consider it too complex for the OP's need.
There is support for 32bit index and then more than 64k faces per $$anonymous$$esh since 2017.3. Check the documentation for $$anonymous$$esh.indexFormat
I'm drawing ships and other objects that are made up of squares. They are destructible, and the player can build/modify them. I'm currently using a texture atlas (because I started with it) then converting it into an array at run time since unity doesn't support atlases in a usable way. I started out using a texture bombing shader, but couldn't find a solution to the problems caused by lack of mipmaps. I'm sure there is a way to do it with tex2Dgrad but I'm not good enough with shaders to figure out how. It also meant I couldn't have any kind of animation or procedurally generated tiles.
Ok, this is more of a procedural generation thing. There are many difficulties in this sector, mainly because of technological limits. The way one would like to do things is too costly in terms of power and storage space, so people have been inventing new ways of ataining procedurally generated worlds. There are also many ways to approach that. You should look at tutorials before actually trying by yourself. Depending on what features your game is supposed to have, the solution might be more or less complex. That is why you should get more information on the different solutions. I don't have links to give you, but it's not that hard to find by using keywords such as procedural generation or infinite worlds or some such.