Search Unity

Particle Implementation Question

Discussion in 'General Graphics' started by N1warhead, Mar 14, 2019.

  1. N1warhead

    N1warhead

    Joined:
    Mar 12, 2014
    Posts:
    3,356
    Hey everyone, I have a question I'm hoping you all can help guide on on the steps to do this.

    Okay let me briefly go over what I'm trying to accomplish.
    I'm making a Battle Royale game themed on Dinosaurs rather than the every day shoot-em up kind.

    You know how there's always that sphere or whatever that shrinks around the map condensing to the center?
    I'm trying to use fire particles so it can look like a controlled fire pushing inward.

    So rather than a sphere/cylinder that shrinks and condenses to the center, I was thinking of using a particle system that produces Fire, smoke, etc. But the problem I can't seem to figure out is - on a flat surface this works fine. But -
    How would I make the particle system recognize the terrain and for example - travel up a mountain side rather than just go through the mountain.
     
  2. Murgilod

    Murgilod

    Joined:
    Nov 12, 2013
    Posts:
    4,844
    ...by enabling world particle collisions?
     
  3. kdgalla

    kdgalla

    Joined:
    Mar 15, 2013
    Posts:
    731
    Are you trying to create one big particle system for the effect? If you create a ring of fire out of lots of small fire objects, then it's pretty easy. You can write script for that object to grab the terrain height at the objects x,y and adjust the position accordingly

    https://docs.unity3d.com/ScriptReference/TerrainData.GetHeight.html

    If your terrain has a lot of meshes, though, you could also use a raycast, pointing down to find the point of intersection.
     
    angrypenguin likes this.
  4. Braineeee

    Braineeee

    Joined:
    Nov 9, 2014
    Posts:
    887
    OHHH. Yay Calculus! That's my S***! Look into partial derivatives!

    So when you take the partial of a graph (in this case your terrain) you get a tangent line (a line that touches the graph at the point your fire is emitting at). If you find the 3d partial derivative there, maybe adding some positive angular difference to the orientation, you will get your fire emitters aiming along or just above the terrain. You'll want the derivative pointing inward to the center of the circle.

    BTW a partial derivative is computed with respect to each variable involved, piecemeal. There's a theorem I believe its called Clairoute's (might be mispelled, its a french name) that says that it does not matter which order you take the partial in because you'll get the same result (in non technical terms).

    EDIT: If you'd rather not do calculus, I suggest an innovative idea! Put your dinosaur warriors on a mountain sinking into hot lava!
     
  5. N1warhead

    N1warhead

    Joined:
    Mar 12, 2014
    Posts:
    3,356

    Hmmm that lava idea is actually pretty cool hahahaha.
    But really - I do appreciate everyone's tips :)
     
  6. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    5,977
    One more suggestion to add to the ... *ahem* ... fire.

    There's three very different situations to this kind of effect you need to deal with. How it's rendered from far away, and how it's rendered when up close. It's going to be unrealistic to have a ring of fire with the many millions of particles needed to fully cover the ring, so you'll an fire effect you can put on a big flat polygon and look like fire from a distance, maybe even relatively close up, and have that on a giant cylinder. It also needs to look correct when scaling the ring up or down, which will be a little harder to do, but still possible.

    I would suggest something like how Rime's fire was done:
    https://simonschreibt.de/gat/stylized-vfx-in-rime/#update1

    The technique is being used to produce a very stylized look, but more realistic fires are possible doing similar stuff:
    https://realtimevfx.com/t/ludvig-lindqvist-sketch-20-wip/7639

    For the noise you could use a panning 3D texture that uses world space coordinates so that as the cylinder shrinks it doesn't appear to change the fire's scale, though you would have to be mindful that while in motion the fire doesn't look like it's animating faster all of a sudden.

    To get the "cylinder of fire" to match the ground there are two options. One would be similar to what was described above: sample the terrain's height and generate a cylinder mesh that conforms to the terrain. The alternative would be to bake out a height map of your entire terrain into another texture, plausibly at a lower resolution, that you can pass to a shader, then either offset the cylinder's UVs or the vertices themselves based on that texture's height for the world position of the vertex / pixel. Apart from the minor cost of storage, it's effectively free.


    When close to the fire wall, obviously you'd want to use particles. And for that I can think of a few ways to go about positioning them. Really there's two parts to the position, the arc and the height. Placing a lot of single points of fire is doable, but expensive as that would require a lot of particle systems to produce anything usable, but might be fine if you can limit the particle systems to only show when you're quite close to the fire wall, but that's kind of lame. It'd be better to use fewer particle systems, potentially even only one particle system, have it do all of the fire wall particles. You can spawn particles on an edge, which is a straight line, or on a circle for which you can limit it to a specific arc range rather than the full 360. With some finesse you should be able to position an arc of any radii, angle, and position you want. But that obviously only deals with a flat surface. But, you could potentially use that same texture to offset the particles' vertex positions with a custom shader! The one downside to this is if your terrain height differences are extreme enough, the particles might be spawning out of view meaning the CPU will cull the particles which makes this option less useful.

    However you could construct a simple mesh that follows the path of the terrain (using the ideas mentioned above) and pass that in as the particle system's shape to spawn from. Generate a basic line mesh with a bit of tessellation to start with, and just update the vertices as needed. Now you can define the exact area and shape the fire should spawn from using a single particle system, and they won't get culled.


    There's still a third case you'll have to think about, being "outside" the ring. Presumably everything outside the inner ring is still on fire. That's going to be expensive to render, so you're going to want to fake this as much as possible. Probably have fire as a screen space post process effect, and have some particles that spawn around the player, and some larger fire effects on points of interest to sell it. For nearby fire, you could use the same dynamic mesh technique, just for a circle around the player instead of a line, or just a simple plane / circle that's oriented roughly to the average ground normal and slightly underground.
     
    SugoiDev and BakeMyCake like this.
  7. BakeMyCake

    BakeMyCake

    Joined:
    May 8, 2017
    Posts:
    90
    To add to what kdgalla wrote - I found this article really helpful when I was doing my particles: https://teapotgames.wixsite.com/tea.../Some-Unorthodox-optimization-tips-with-Unity

    The unified particle system described there fits the description of what you need. The code examples are there, just use Emit with the position and rotation you want. How you get position and rotation is up to you, but we don't have enough info to suggest anything specific.
     
    bgolus likes this.