Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Custom particle emitter. Rendering billboards.

Discussion in 'Scripting' started by CyberFox01, Apr 9, 2013.

  1. CyberFox01

    CyberFox01

    Joined:
    Oct 5, 2012
    Posts:
    23
    I'm creating my custom particle system. (Solely because i prefer scripting particles rather than using the editor)

    Currently I'm rendering all planes as 2 polygons who share 4 vertices. The position of these vertices determine the facing.
    the only info on the particles i have is a vector3. Currently i just offset them a bit so the vertices don't render in in the same position making them all face in one axis as seen in the snippet below:
    Code (csharp):
    1. vertices[vi  ] = new Vector3(particle.position.x-(10*particle.scale.x), particle.position.y, particle.position.z+(10*particle.scale.x));
    2. vertices[vi+1] = new Vector3(particle.position.x-(10*particle.scale.x), particle.position.y, particle.position.z-(10*particle.scale.x));
    3. vertices[vi+2] = new Vector3(particle.position.x+(10*particle.scale.x), particle.position.y, particle.position.z-(10*particle.scale.x));
    4. vertices[vi+3] = new Vector3(particle.position.x+(10*particle.scale.x), particle.position.y, particle.position.z+(10*particle.scale.x))
    So question is: How do i offset these vertices so the face will be looking at the camera?
    I've tried googling for the source of unity's particle emitter, to see how they did, but no luck.
     
  2. Ted-Chirvasiu

    Ted-Chirvasiu

    Joined:
    Sep 7, 2010
    Posts:
    381
    Hello, sorry, i am not very familiar with the particles and custom particle system in Unity but i assume that what you want to do is to set the Particle Rotation to LookAt your camera rather than modifying the meshes. It would be faster too.

    Check those out. I hope it helps, good luck!
     
    Last edited: Apr 9, 2013
  3. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    If I were to do this then I'd use Camera.current.transform.right and Camera.current.transform.up, though I'd cache them rather than referencing them per particle.

    I'd strongly suggest looking into custom scripting Shuriken, though. Particles are expensive enough as it is without forcing them into slower executing, single-threadded script level code which does all of the work on CPU and then pushes it all to the GPU.

    I hope that at the very least you're doing all of your rendering work in a single script, rather than having each particle draw itself.
     
  4. CyberFox01

    CyberFox01

    Joined:
    Oct 5, 2012
    Posts:
    23
    I'm using a polymorphic class structure. I earlier had a material on each particle, but apparently 16500 materials instances on a single mesh. Well lets just say i only used that solution for the 30sec seconds it took to force kill unity.

    So now they're split into groups of particles who share the same material instance and the superclass handles the rest.. zept billboards.


    i could make shuriken render my particles. But haven't looked into it enough.

    Code (csharp):
    1. public abstract class particle {
    2.     public particle(){
    3.         position = new Vector3();
    4.         scale = Vector3.one;
    5.         rotation = Quaternion.identity;
    6.         endOfLife=false;
    7.     }
    8.     public Vector3 position;
    9.     public Vector3 scale; // 3d scale cause we don't know how particles look
    10.     //public Quaternion angularVelocity;
    11.     public Quaternion rotation;
    12.     public bool endOfLife;
    13.  
    14.     // per particle per frame
    15.     public abstract void simulate();
    16. }
    17. public class particleGroup{
    18.     public Material groupMaterial;
    19.     public List<particle> particles;
    20. }
    I know performance wise an array is faster than a list. But i need to manage an unknown amount of items so this is easier ^^

    Is Shuriken able to just take an array of particles and handle the rendering for me?
     
  5. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,516
    Ok, calling simulate() on 16,500 objects means that you've got the overhead of 16,500 function calls, plus all of the object de-referencing and such. You're going to be much better off, I think, having one single loop in a single class that iterates over all of the particle info as structs. With particle systems taking care of your cache is especially important for performance, and breaking things up over different objects with distinct function calls thrashes the crap out of your cache.

    An array, by the way, might not be faster than a list. As far as I'm aware the type of list you're using is in fact internally implemented as an array, and just has a bunch of convenience code on top. I haven't tested, but I expect that adding objects is significantly slower, but accessing them is probably approximately as fast. (But as I said, untested.)

    And yes, Shuriken is able to take an array of particles and do the rendering for you. I'd strongly suggest that approach, because even if you make the best possible MonoBehaviour particle system possible, chances are it'll be way slower than the built in native one. For starters, even if you generate your particles as efficiently as possible you've got a whole new mesh to re-write to the GPU each frame, where the native stuff is most likely taking advantage of functionality specifically designed to minimise that hit.
     
  6. vidhvat

    vidhvat

    Joined:
    Jul 6, 2013
    Posts:
    2
    So why is it that Shuriken decides to cull all particles if the emitter is outside the view frustum?

    Just spent an hour on converting my foliage generator into Shuriken, and now this.
     
  7. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    builtin array is faster than list due to the fact its sequential addressing, while list has pointer to next list item. But the speed difference only becomes measurable once you hit really large array sizes.
     
  8. CyberFox01

    CyberFox01

    Joined:
    Oct 5, 2012
    Posts:
    23
    Sorry for taking so long. Life is busy.

    Anyways. I tried the above solution just now (moving it to Shuriken). And it tremendously improved the performance and went way past the current 16500 particle limit. This really is witchcraft.

    But now I'm having the same problem as Vids. As soon as the gameObject is not in view, my skies just disappear.

    Also: I can't seem to figure out how to run with multiple materials, previously i used submeshes but with Shuriken i don't know.

    Graphs visualizing data
     
    Last edited: Jul 30, 2013