Skip to content

Commit

Permalink
Update recent particle optimizations to fix edge case slowdowns (#5385)
Browse files Browse the repository at this point in the history
#5328 added a very useful culling for particles created by specific particle effects (ie weapons, now beams), though in an effort to simplify the culling process, that PR removed the necessary culling of default smoke on ships. This PR restores the culling of default smoke while also keeping the new culling of particle specific effects. Tested and works as expected, including fixing the slowdowns caused by the aforementioned removal of smoke effect culls.
  • Loading branch information
wookieejedi authored Apr 30, 2023
1 parent e5301b7 commit 5a1ac87
Show file tree
Hide file tree
Showing 7 changed files with 42 additions and 11 deletions.
5 changes: 3 additions & 2 deletions code/particle/effects/ParticleEmitterEffect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ bool ParticleEmitterEffect::processSource(ParticleSource* source) {
source->getOrigin()->getGlobalPosition(&emitter.pos);
emitter.normal = source->getOrientation()->getDirectionVector(source->getOrigin());

emit(&emitter, PARTICLE_BITMAP, m_particleBitmap);
emit(&emitter, PARTICLE_BITMAP, m_particleBitmap, m_range);

return false;
}
Expand All @@ -28,11 +28,12 @@ void ParticleEmitterEffect::pageIn() {
bm_page_in_texture(m_particleBitmap);
}

void ParticleEmitterEffect::setValues(const particle_emitter& emitter, int bitmap) {
void ParticleEmitterEffect::setValues(const particle_emitter& emitter, int bitmap, float range) {
Assert(bm_is_valid(bitmap));

m_emitter = emitter;
m_particleBitmap = bitmap;
m_range = range;
}
}
}
3 changes: 2 additions & 1 deletion code/particle/effects/ParticleEmitterEffect.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ class ParticleEmitterEffect: public ParticleEffect {
private:
particle_emitter m_emitter;
int m_particleBitmap = -1;
float m_range = -1;

public:
ParticleEmitterEffect();
Expand All @@ -24,7 +25,7 @@ class ParticleEmitterEffect: public ParticleEffect {

void pageIn() override;

void setValues(const particle_emitter& emitter, int bitmap);
void setValues(const particle_emitter& emitter, int bitmap, float range);
};
}
}
Expand Down
35 changes: 32 additions & 3 deletions code/particle/particle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,17 @@ namespace

return alpha;
}

inline int get_percent(int count)
{
if (count == 0)
return 0;

// this should basically return a scale like:
// 50, 75, 100, 125, 150, ...
// based on value of 'count' (detail level)
return (50 + (25 * (count - 1)));
}
}

namespace particle
Expand Down Expand Up @@ -551,15 +562,33 @@ namespace particle

// Creates a bunch of particles. You pass a structure
// rather than a bunch of parameters.
void emit(particle_emitter* pe, ParticleType type, int optional_data)
void emit(particle_emitter* pe, ParticleType type, int optional_data, float range)
{
int i, n;

if (!Particles_enabled)
return;

int n1 = (int)(pe->num_low * 1.25);
int n2 = (int)(pe->num_high * 1.25);
int n1, n2;

// Account for detail
int percent = get_percent(Detail.num_particles);

//Particle rendering drops out too soon. Seems to be around 150 m. Is it detail level controllable? I'd like it to be 500-1000
float min_dist = 125.0f;
float dist = vm_vec_dist_quick(&pe->pos, &Eye_position) / range;
if (dist > min_dist)
{
percent = fl2i(i2fl(percent) * min_dist / dist);
if (percent < 1)
{
return;
}
}
//mprintf(( "Dist = %.1f, percent = %d%%\n", dist, percent ));

n1 = (pe->num_low * percent) / 100;
n2 = (pe->num_high * percent) / 100;

// How many to emit?
n = Random::next(n1, n2);
Expand Down
2 changes: 1 addition & 1 deletion code/particle/particle.h
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ namespace particle

// Creates a bunch of particles. You pass a structure
// rather than a bunch of parameters.
void emit(particle_emitter *pe, ParticleType type, int optional_data);
void emit(particle_emitter *pe, ParticleType type, int optional_data, float range = 1.0);
}

#endif // _PARTICLE_H
Expand Down
2 changes: 1 addition & 1 deletion code/ship/ship.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8931,7 +8931,7 @@ static void ship_dying_frame(object *objp, int ship_num)
pe.max_rad = pef.max_rad; // * objp->radius;

if (pe.num_high > 0) {
particle::emit( &pe, particle::PARTICLE_SMOKE2, 0 );
particle::emit( &pe, particle::PARTICLE_SMOKE2, 0, 50 );
}

// do sound - maybe start a random sound, if it has played far enough.
Expand Down
2 changes: 1 addition & 1 deletion code/ship/shipfx.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2013,7 +2013,7 @@ static void maybe_fireball_wipe(clip_ship* half_ship, sound_handle* handle_array
}

if (pe.num_high > 0) {
particle::emit( &pe, particle::PARTICLE_SMOKE2, 0 );
particle::emit( &pe, particle::PARTICLE_SMOKE2, 0, range );
}

if (sip->generic_debris_model_num >= 0) {
Expand Down
4 changes: 2 additions & 2 deletions code/weapon/weapons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2200,7 +2200,7 @@ int parse_weapon(int subtype, bool replace, const char *filename)
emitter.vel = vmd_zero_vector;

auto emitterEffect = new ParticleEmitterEffect();
emitterEffect->setValues(emitter, effectIndex);
emitterEffect->setValues(emitter, effectIndex, 10.0f);
wip->piercing_impact_effect = ParticleManager::get()->addEffect(emitterEffect);

if (back_velocity != 0.0f)
Expand All @@ -2211,7 +2211,7 @@ int parse_weapon(int subtype, bool replace, const char *filename)
emitter.num_low /= 2;

auto secondaryEffect = new ParticleEmitterEffect();
secondaryEffect->setValues(emitter, effectIndex);
secondaryEffect->setValues(emitter, effectIndex, 10.0f);
wip->piercing_impact_secondary_effect = ParticleManager::get()->addEffect(secondaryEffect);
}
}
Expand Down

0 comments on commit 5a1ac87

Please sign in to comment.