sarbian / SmokeScreen

BSD 2-Clause "Simplified" License
16 stars 14 forks source link

Add an option to emit particles on 'LateUpdate' #34

Closed PatPL closed 5 years ago

PatPL commented 5 years ago

There might be some garbage in diff, because I didn't notice my VS was configured to use tabs. Sorry.

Every major change should be commented.

Changes overview:

Other pics:

In no particular order


Tweaked UI. Now you can view current particle count per-plume


Contrary to what the code said, the collisions work just fine in either Update.


I didn't notice any performance drop caused by either the previous, or this pull request.


High velocity plumes are now possible. The segmenting in leftmost plume's gradient is because the particles were emitted in batches. This could be fixed by pre-removing remaining life from emitted particles (Something to look into in the future)


Low FPS default, and decluster + emitOnUpdate comparison


decluster and decluster + emitOnUpdate comparison. Notice, how the plume separates from the leftmost plume.


Default, decluster and decluster + emitOnUpdate side to side comparison. Notice, how the rightmost plume doesn't react to FPS changes. GIF too large. Click here


Default and decluster + emitOnUpdate comparison in RealPlume. The only change in configs between these two, is adding the snippet below to plume on the right. The FPS was around 20 (The usual FPS of a standard RO install :P)

decluster = true
emitOnUpdate = true

sarbian commented 5 years ago

I ll cleanup the tabs... Foreach is usually bad with Unity since it allocates memory while for does not. On a List it is OK but still slower than a for. Use of Linq should be limited to one shot code since it does allocate.

sarbian commented 5 years ago

I guess I should not post the PR comment from work because I always do it fast and forget basic manner : Thanks for the contribution. It does look great! Given the current feedback I will most likely move all emission to LateUpdate to cleanup the code a bit.

PatPL commented 5 years ago

Oh, one more idea I had: Try removing particle lifetime on emit, if more than one was emitted. currently the separate batches are very visible on very low FPS. I didn't test it as I'm working on something else right now, but it shouldn't be hard to implement if you know what to do.

Something like this:

// in PersistentKSPShurikenEmitter.cs, in Emit (int ThisInUpdate, int TotalInUpdate):
-- emitParams.startLifetime = Random.Range(minEnergy, maxEnergy);
++ emitParams.startLifetime = Random.Range(minEnergy, maxEnergy) - (Time.deltaTime * (ThisInUpdate - 1) / TotalInUpdate);

Below is the example of what happens: Notice how the batches of particles emitted each frame is clearly visible. obraz

Let me know if that improves things. You can artificially lower FPS by quickly resizing the debug console window, to test things. Increase emission, if the frams are not clearly visible

sarbian commented 5 years ago

I don't really see how changing how long the particle stays will separate them better. And it seems like it may impact the apparence of the plume a lot.

PatPL commented 5 years ago

It will not separate them better. I want to improve the gradient between batches of particles spawned in different frames.

Also, I believe there might be an error in that implementation example I gave earlier. Implementing this would require changing particle's remaining lifetime, and the start size would need to be manually set on emit. (Particle grow equations already work with deltaTime, so it can work with fractions of deltaTime)

obraz

You can clearly see the particle batches on this gif. Notice how apparent are the color animation steps on the leftmost plume. You can clearly see which particles were spawned on which frame. obraz

I hope you see what I want to achieve here, and what the problem actually is.

I'll try to do this myself, and see how that looks like. I'll send another pull request, or comment here, depending on my results

sarbian commented 5 years ago

That makes more sense. It may be hard to properly emulate this with all the curves in actions

PatPL commented 5 years ago

Unless SmokeScreen does stuff behind the scenes I don't know about, this seems like a quite straightforward thing to implement.

Particle size:

// These multipliers already work with Time.deltaTime
double logGrowConst = Time.deltaTime * logarithmicGrow * logarithmicGrowScale;
float linGrowConst = (float)(Time.deltaTime * linearGrow * averageSize);
float growConst = Mathf.Pow( 1 + sizeGrow, Time.deltaTime);
// later...
particle.startSize = particle.startSize * growConst;
particle.startSize += (float) ((logGrowConst / (1 + (particle.startLifetime - particle.remainingLifetime) * logarithmicGrow)) * averageSize);
particle.startSize += linGrowConst;
// Therefore, I believe this code could be copied to Emit(), and applied to emitParams.startSize
// It would just swap out 'Time.deltaTime' to '(Time.deltaTime * ThisInUpdate / TotalInUpdate)'
// (For particles with ThisInUpdate > 0)

As for the color gradient, it works with float lifePercentage = 1 - (particle.remainingLifetime / particle.startLifetime); so preremoving particle's remaining lifetime on Emit () should do the trick

emitParams.startLifetime = Random.Range(minEnergy, maxEnergy);
// Problem is, it'd need to get all particles after emitting, to remove their remainingLifetime
// as remainingLifetime is not a property of 'EmitParams'

// once you access the particles spawned in this frame's Emit () calls, iterate over these particles (In EmitterOnUpdate ()) and remove the lifetime
particle.remainingLifetime -= (Time.deltaTime * ThisInUpdate / TotalInUpdate);

Let me know if I'm missing something.

Like I said, I'll start working on it right now.

edit: ThisInUpdate starts from 0

sarbian commented 5 years ago

From my half awake state it seems everything is there.

PatPL commented 5 years ago

Same plume settings, the higher one with current SmokeScreen, lower one with preapplied size.

obraz

Seems to work well, so far. (Might look a bit off. I guess that's because logScale uses remaining lifetime, and I didn't do that yet)

I'll start working on the lifetime reduction

PatPL commented 5 years ago

@sarbian #36