diff --git a/assets/voxygen/shaders/particle-vert.glsl b/assets/voxygen/shaders/particle-vert.glsl index 46dea26b5a..ad1165c0dd 100644 --- a/assets/voxygen/shaders/particle-vert.glsl +++ b/assets/voxygen/shaders/particle-vert.glsl @@ -149,7 +149,7 @@ void main() { vec3(rand2 * 0.02, rand3 * 0.02, 1.0 + rand4 * 0.1) ), vec3(linear_scale(0.5)), - vec4(1, 1, 1, start_end(1.0, 0.0)), + vec4(vec3(0.8, 0.8, 1) * 0.5, start_end(1.0, 0.0)), spin_in_axis(vec3(rand6, rand7, rand8), rand9 * 3 + lifetime * 0.5) ); } else if (inst_mode == FIRE) { @@ -295,7 +295,7 @@ void main() { vec3(rand3 * 2, rand4 * 2, rand5 * 2) ), vec3(0.8), - vec4(vec3(0, 2.5, 1.5 + rand7 * 0.7), 1), + 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) ); } else if (inst_mode == FLAMETHROWER) { @@ -303,7 +303,7 @@ void main() { attr = Attr( (inst_dir * lifetime / inst_lifespan) + vec3(rand0, rand1, rand2) * (lifetime * 5 + 0.25), vec3(0.6 + rand3 * 0.5 + lifetime / inst_lifespan * 5), - vec4(3, 1.6 + rand5 * 0.3 - 0.6 * lifetime / inst_lifespan, 0.2, start_end(1.0, 0.0) /*0.8 - 0.6 * lifetime / inst_lifespan*/), + 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*/), spin_in_axis(vec3(rand6, rand7, rand8), lifetime / inst_lifespan * 10 + 3 * rand9) ); } else if (inst_mode == FIRE_SHOCKWAVE) { diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index d0f4337edc..a8f450200b 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -535,9 +535,14 @@ impl Scene { let loaded_distance = (0.98 * self.loaded_distance + 0.02 * scene_data.loaded_distance).max(0.01); - // Update light constants + // Reset lights ready for the next tick let lights = &mut self.light_data; lights.clear(); + + // Maintain the particles. + self.particle_mgr.maintain(renderer, &scene_data, &self.terrain, lights); + + // Update light constants lights.extend( ( &scene_data.state.ecs().read_storage::(), @@ -989,10 +994,6 @@ impl Scene { // Remove unused figures. self.figure_mgr.clean(scene_data.tick); - // Maintain the particles. - self.particle_mgr - .maintain(renderer, &scene_data, &self.terrain); - // Maintain audio self.sfx_mgr.maintain( audio, diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index 572618c75d..acb7426a2b 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -3,7 +3,7 @@ use crate::{ mesh::{greedy::GreedyMesh, Meshable}, render::{ pipelines::particle::ParticleMode, GlobalModel, Instances, LodData, Model, - ParticleInstance, ParticlePipeline, Renderer, + ParticleInstance, ParticlePipeline, Renderer, Light, }, }; use common::{ @@ -137,6 +137,7 @@ impl ParticleMgr { renderer: &mut Renderer, scene_data: &SceneData, terrain: &Terrain, + lights: &mut Vec, ) { span!(_guard, "maintain", "ParticleMgr::maintain"); if scene_data.particles_enabled { @@ -150,7 +151,7 @@ impl ParticleMgr { // add new Particle self.maintain_body_particles(scene_data); self.maintain_boost_particles(scene_data); - self.maintain_beam_particles(scene_data); + self.maintain_beam_particles(scene_data, lights); self.maintain_block_particles(scene_data, terrain); self.maintain_shockwave_particles(scene_data); } else { @@ -359,7 +360,7 @@ impl ParticleMgr { } } - fn maintain_beam_particles(&mut self, scene_data: &SceneData) { + fn maintain_beam_particles(&mut self, scene_data: &SceneData, lights: &mut Vec) { let state = scene_data.state; let ecs = state.ecs(); let time = state.get_time(); @@ -375,6 +376,12 @@ impl ParticleMgr { let particle_ori = b.particle_ori.unwrap_or(*ori.vec()); if b.stage_section == StageSection::Cast { if b.static_data.base_hps > 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_beam( b.static_data.beam_duration, @@ -388,6 +395,12 @@ impl ParticleMgr { let mut rng = thread_rng(); let (from, to) = (Vec3::::unit_z(), particle_ori); let m = Mat3::::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(