mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Improve particles
This commit is contained in:
parent
952a77f94d
commit
a4513fe09d
@ -1,15 +1,15 @@
|
|||||||
BasicBeam(
|
BasicBeam(
|
||||||
buildup_duration: 0.25,
|
buildup_duration: 0.25,
|
||||||
recover_duration: 0.25,
|
recover_duration: 0.25,
|
||||||
beam_duration: 0.5,
|
beam_duration: 1.5,
|
||||||
base_hps: 0,
|
base_hps: 0,
|
||||||
base_dps: 150,
|
base_dps: 150,
|
||||||
tick_rate: 3.0,
|
tick_rate: 3.0,
|
||||||
range: 15.0,
|
range: 15.0,
|
||||||
max_angle: 22.5,
|
max_angle: 10.0,
|
||||||
lifesteal_eff: 0.0,
|
lifesteal_eff: 0.0,
|
||||||
energy_regen: 0,
|
energy_regen: 0,
|
||||||
energy_cost: 1,
|
energy_cost: 1,
|
||||||
energy_drain: 350,
|
energy_drain: 350,
|
||||||
orientation_behavior: Normal,
|
orientation_behavior: Normal,
|
||||||
)
|
)
|
||||||
|
@ -86,6 +86,18 @@ float linear_scale(float factor) {
|
|||||||
return lifetime * factor;
|
return lifetime * factor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float percent() {
|
||||||
|
return lifetime / inst_lifespan;
|
||||||
|
}
|
||||||
|
|
||||||
|
float slow_end(float factor) {
|
||||||
|
return (1 + factor) * percent() / (percent() + factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
float slow_start(float factor) {
|
||||||
|
return 1-(1 + factor) * (1-percent()) / ((1-percent()) + factor);
|
||||||
|
}
|
||||||
|
|
||||||
float start_end(float from, float to) {
|
float start_end(float from, float to) {
|
||||||
return mix(from, to, lifetime / inst_lifespan);
|
return mix(from, to, lifetime / inst_lifespan);
|
||||||
}
|
}
|
||||||
@ -124,10 +136,10 @@ vec3 spiral_motion(vec3 line, float radius, float time_function) {
|
|||||||
vec3 axis2 = perp_axis1(line);
|
vec3 axis2 = perp_axis1(line);
|
||||||
vec3 axis3 = perp_axis2(line, axis2);
|
vec3 axis3 = perp_axis2(line, axis2);
|
||||||
|
|
||||||
return line * time_function + vec3(
|
return vec3(
|
||||||
radius * cos(10 * time_function - inst_time) * axis2.x + radius * sin(10 * time_function - inst_time) * axis3.x,
|
radius * cos(time_function) * axis2.x + radius * sin(time_function) * axis3.x,
|
||||||
radius * cos(10 * time_function - inst_time) * axis2.y + radius * sin(10 * time_function - inst_time) * axis3.y,
|
radius * cos(time_function) * axis2.y + radius * sin(time_function) * axis3.y,
|
||||||
radius * cos(10 * time_function - inst_time) * axis2.z + radius * sin(10 * time_function - inst_time) * axis3.z);
|
radius * cos(time_function) * axis2.z + radius * sin(time_function) * axis3.z);
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@ -161,7 +173,7 @@ void main() {
|
|||||||
f_reflect = 0.0; // Fire doesn't reflect light, it emits it
|
f_reflect = 0.0; // Fire doesn't reflect light, it emits it
|
||||||
attr = Attr(
|
attr = Attr(
|
||||||
linear_motion(
|
linear_motion(
|
||||||
vec3(normalize(vec2(rand0, rand1)) * 0.25, 0.3),
|
vec3(0.0),
|
||||||
vec3(rand2 * 0.1, rand3 * 0.1, 2.0 + rand4 * 1.0)
|
vec3(rand2 * 0.1, rand3 * 0.1, 2.0 + rand4 * 1.0)
|
||||||
),
|
),
|
||||||
vec3(1.0),
|
vec3(1.0),
|
||||||
@ -317,26 +329,25 @@ void main() {
|
|||||||
} else if (inst_mode == ENERGY_NATURE) {
|
} else if (inst_mode == ENERGY_NATURE) {
|
||||||
f_reflect = 0.0;
|
f_reflect = 0.0;
|
||||||
attr = Attr(
|
attr = Attr(
|
||||||
linear_motion(
|
inst_dir * slow_end(0.03) + spiral_motion(vec3(rand1, rand2, rand3),
|
||||||
vec3(rand0 * 1, rand1 * 1, rand2 * 1),
|
0.2 * (rand4 + 1.3) * slow_end(0.02), percent() * 3 * (rand4 + 4.0) + rand0),
|
||||||
vec3(rand3 * 2, rand4 * 2, rand5 * 2)
|
vec3(1.0),
|
||||||
),
|
|
||||||
vec3(0.8),
|
|
||||||
vec4(vec3(0, 2.5, 1.5 + rand7 * 0.7), start_end(1.0, 0.0)),
|
vec4(vec3(0, 2.5, 1.5 + rand7 * 0.7), start_end(1.0, 0.0)),
|
||||||
spin_in_axis(vec3(rand6, rand7, rand8), rand9 * 3)
|
spin_in_axis(vec3(rand6, rand7, rand8), rand9 * 3)
|
||||||
);
|
);
|
||||||
} else if (inst_mode == FLAMETHROWER) {
|
} else if (inst_mode == FLAMETHROWER) {
|
||||||
f_reflect = 0.0; // Fire doesn't reflect light, it emits it
|
f_reflect = 0.0; // Fire doesn't reflect light, it emits it
|
||||||
attr = Attr(
|
attr = Attr(
|
||||||
(inst_dir * lifetime / inst_lifespan) + vec3(rand0, rand1, rand2) * (lifetime * 5 + 0.25),
|
inst_dir * ((rand0+1.0)/2 + 0.5) * slow_end(0.2) + /*0.4 * vec3(rand0,
|
||||||
vec3(0.6 + rand3 * 0.5 + lifetime / inst_lifespan * 5),
|
rand1, rand2) * slow_end(0.1)*/ + 0.1 * grav_vel(earth_gravity),
|
||||||
vec4(3, 1.6 + rand5 * 0.3 - 0.4 * lifetime / inst_lifespan, 0.2, start_end(1.0, 0.0) /*0.8 - 0.6 * lifetime / inst_lifespan*/),
|
vec3((3 * (1 - slow_start(0.1)))),
|
||||||
spin_in_axis(vec3(rand6, rand7, rand8), lifetime / inst_lifespan * 10 + 3 * rand9)
|
vec4(3, 1.6 + rand5 * 0.3 - 0.4 * percent(), 0.2, start_end(1.0, 0.0)),
|
||||||
|
spin_in_axis(vec3(rand6, rand7, rand8), percent() * 10 + 3 * rand9)
|
||||||
);
|
);
|
||||||
} else if (inst_mode == FIRE_SHOCKWAVE) {
|
} else if (inst_mode == FIRE_SHOCKWAVE) {
|
||||||
f_reflect = 0.0; // Fire doesn't reflect light, it emits it
|
f_reflect = 0.0; // Fire doesn't reflect light, it emits it
|
||||||
attr = Attr(
|
attr = Attr(
|
||||||
vec3(rand0, rand1, lifetime * 10 + rand2),
|
vec3(rand0, rand1, lifetime * 1 + rand2),
|
||||||
vec3(1.6 + rand3 * 1.5 + 10 * (lifetime + inst_lifespan)),
|
vec3(1.6 + rand3 * 1.5 + 10 * (lifetime + inst_lifespan)),
|
||||||
vec4(3, 1.6 + rand7 * 0.3 - 5 * inst_lifespan + 2 * lifetime, 0.2, start_end(1.0, 0.0) /*0.8 - 3.5 * inst_lifespan*/),
|
vec4(3, 1.6 + rand7 * 0.3 - 5 * inst_lifespan + 2 * lifetime, 0.2, start_end(1.0, 0.0) /*0.8 - 3.5 * inst_lifespan*/),
|
||||||
spin_in_axis(vec3(rand3, rand4, rand5), rand6)
|
spin_in_axis(vec3(rand3, rand4, rand5), rand6)
|
||||||
|
@ -139,7 +139,7 @@ impl Instance {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_beam(
|
pub fn new_directed(
|
||||||
inst_time: f64,
|
inst_time: f64,
|
||||||
lifespan: f32,
|
lifespan: f32,
|
||||||
inst_mode: ParticleMode,
|
inst_mode: ParticleMode,
|
||||||
|
@ -66,14 +66,15 @@ impl ParticleMgr {
|
|||||||
self.particles.resize_with(
|
self.particles.resize_with(
|
||||||
self.particles.len() + (200.0 * power.abs()) as usize,
|
self.particles.len() + (200.0 * power.abs()) as usize,
|
||||||
|| {
|
|| {
|
||||||
Particle::new(
|
Particle::new_directed(
|
||||||
Duration::from_secs(1),
|
Duration::from_secs_f32(rng.gen_range(1.0, 8.0)),
|
||||||
time,
|
time,
|
||||||
ParticleMode::EnergyNature,
|
ParticleMode::EnergyNature,
|
||||||
|
*pos,
|
||||||
*pos + Vec3::<f32>::zero()
|
*pos + Vec3::<f32>::zero()
|
||||||
.map(|_| rng.gen_range(-1.0..1.0))
|
.map(|_| rng.gen_range(-1.0..1.0))
|
||||||
.normalized()
|
.normalized()
|
||||||
* *radius,
|
* rng.gen_range(1.0, radius)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -81,10 +82,11 @@ impl ParticleMgr {
|
|||||||
self.particles.resize_with(
|
self.particles.resize_with(
|
||||||
self.particles.len() + (200.0 * power.abs()) as usize,
|
self.particles.len() + (200.0 * power.abs()) as usize,
|
||||||
|| {
|
|| {
|
||||||
Particle::new(
|
Particle::new_directed(
|
||||||
Duration::from_secs(1),
|
Duration::from_secs(2),
|
||||||
time,
|
time,
|
||||||
ParticleMode::CampfireFire,
|
ParticleMode::FlameThrower,
|
||||||
|
*pos,
|
||||||
*pos + Vec3::<f32>::zero()
|
*pos + Vec3::<f32>::zero()
|
||||||
.map(|_| rng.gen_range(-1.0..1.0))
|
.map(|_| rng.gen_range(-1.0..1.0))
|
||||||
.normalized()
|
.normalized()
|
||||||
@ -295,7 +297,7 @@ impl ParticleMgr {
|
|||||||
Particle::new(
|
Particle::new(
|
||||||
Duration::from_millis(250),
|
Duration::from_millis(250),
|
||||||
time,
|
time,
|
||||||
ParticleMode::EnergyNature,
|
ParticleMode::CampfireSmoke,
|
||||||
pos.0,
|
pos.0,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
@ -376,6 +378,7 @@ impl ParticleMgr {
|
|||||||
.join()
|
.join()
|
||||||
.filter(|(_, _, b)| b.creation.map_or(true, |c| (c + dt as f64) >= time))
|
.filter(|(_, _, b)| b.creation.map_or(true, |c| (c + dt as f64) >= time))
|
||||||
{
|
{
|
||||||
|
//
|
||||||
let range = beam.properties.speed * beam.properties.duration.as_secs_f32();
|
let range = beam.properties.speed * beam.properties.duration.as_secs_f32();
|
||||||
if beam
|
if beam
|
||||||
.properties
|
.properties
|
||||||
@ -393,6 +396,58 @@ impl ParticleMgr {
|
|||||||
pos.0,
|
pos.0,
|
||||||
pos.0 + *ori.look_dir() * range,
|
pos.0 + *ori.look_dir() * range,
|
||||||
));
|
));
|
||||||
|
//
|
||||||
|
if let CharacterState::BasicBeam(b) = character_state {
|
||||||
|
let particle_ori = b.particle_ori.unwrap_or_else(|| ori.look_vec());
|
||||||
|
if b.stage_section == StageSection::Cast {
|
||||||
|
if b.static_data.base_hps > 0.0 {
|
||||||
|
// Emit a light when using healing
|
||||||
|
lights.push(Light::new(pos.0 + b.offset, Rgb::new(0.1, 1.0, 0.15), 1.0));
|
||||||
|
for i in 0..self.scheduler.heartbeats(Duration::from_millis(1)) {
|
||||||
|
self.particles.push(Particle::new_directed(
|
||||||
|
b.static_data.beam_duration,
|
||||||
|
time + i as f64 / 1000.0,
|
||||||
|
ParticleMode::HealingBeam,
|
||||||
|
pos.0 + particle_ori * 0.5 + b.offset,
|
||||||
|
pos.0 + particle_ori * b.static_data.range + b.offset,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let mut rng = thread_rng();
|
||||||
|
let (from, to) = (Vec3::<f32>::unit_z(), particle_ori);
|
||||||
|
let m = Mat3::<f32>::rotation_from_to_3d(from, to);
|
||||||
|
// Emit a light when using flames
|
||||||
|
lights.push(Light::new(
|
||||||
|
pos.0 + b.offset,
|
||||||
|
Rgb::new(1.0, 0.25, 0.05).map(|e| e * rng.gen_range(0.8..1.2)),
|
||||||
|
2.0,
|
||||||
|
));
|
||||||
|
self.particles.resize_with(
|
||||||
|
self.particles.len()
|
||||||
|
+ 2 * usize::from(
|
||||||
|
self.scheduler.heartbeats(Duration::from_millis(1)),
|
||||||
|
),
|
||||||
|
|| {
|
||||||
|
let phi: f32 =
|
||||||
|
rng.gen_range(0.0..b.static_data.max_angle.to_radians());
|
||||||
|
let theta: f32 = rng.gen_range(0.0..2.0 * PI);
|
||||||
|
let offset_z = Vec3::new(
|
||||||
|
phi.sin() * theta.cos(),
|
||||||
|
phi.sin() * theta.sin(),
|
||||||
|
phi.cos(),
|
||||||
|
);
|
||||||
|
let random_ori = offset_z * m * Vec3::new(-1.0, -1.0, 1.0);
|
||||||
|
Particle::new_directed(
|
||||||
|
b.static_data.beam_duration,
|
||||||
|
time,
|
||||||
|
ParticleMode::FlameThrower,
|
||||||
|
pos.0 + random_ori * 0.5 + b.offset,
|
||||||
|
pos.0 + random_ori * b.static_data.range + b.offset,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
//
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
@ -612,25 +667,27 @@ impl ParticleMgr {
|
|||||||
|
|
||||||
let position_snapped = ((position / scale).floor() + 0.5) * scale;
|
let position_snapped = ((position / scale).floor() + 0.5) * scale;
|
||||||
|
|
||||||
self.particles.push(Particle::new(
|
self.particles.push(Particle::new_directed(
|
||||||
Duration::from_millis(250),
|
Duration::from_secs(2),
|
||||||
time,
|
time,
|
||||||
ParticleMode::GroundShockwave,
|
ParticleMode::FlameThrower,
|
||||||
position_snapped,
|
position_snapped,
|
||||||
|
Vec3::new(0.0, 0.0, 10.0) + position_snapped,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for d in 0..3 * distance as i32 {
|
for d in 0..8 * distance as i32 {
|
||||||
let arc_position = theta - radians / 2.0 + dtheta * d as f32 / 3.0;
|
let arc_position = theta - radians / 2.0 + dtheta * d as f32 / 3.0;
|
||||||
|
|
||||||
let position = pos.0
|
let diff = distance * Vec3::new(arc_position.cos(), arc_position.sin(), 0.0);
|
||||||
+ distance * Vec3::new(arc_position.cos(), arc_position.sin(), 0.0);
|
let position = pos.0 + diff;
|
||||||
|
|
||||||
self.particles.push(Particle::new(
|
self.particles.push(Particle::new_directed(
|
||||||
Duration::from_secs_f32(distance / 50.0),
|
Duration::from_millis(500),
|
||||||
time,
|
time,
|
||||||
ParticleMode::FireShockwave,
|
ParticleMode::FlameThrower,
|
||||||
position,
|
pos.0 + diff * 0.9,
|
||||||
|
Vec3::new(0.0, 0.0, 2.0) + position,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -805,7 +862,7 @@ impl Particle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_beam(
|
fn new_directed(
|
||||||
lifespan: Duration,
|
lifespan: Duration,
|
||||||
time: f64,
|
time: f64,
|
||||||
mode: ParticleMode,
|
mode: ParticleMode,
|
||||||
@ -814,7 +871,13 @@ impl Particle {
|
|||||||
) -> Self {
|
) -> Self {
|
||||||
Particle {
|
Particle {
|
||||||
alive_until: time + lifespan.as_secs_f64(),
|
alive_until: time + lifespan.as_secs_f64(),
|
||||||
instance: ParticleInstance::new_beam(time, lifespan.as_secs_f32(), mode, pos1, pos2),
|
instance: ParticleInstance::new_directed(
|
||||||
|
time,
|
||||||
|
lifespan.as_secs_f32(),
|
||||||
|
mode,
|
||||||
|
pos1,
|
||||||
|
pos2,
|
||||||
|
),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user