diff --git a/assets/voxygen/shaders/include/light.glsl b/assets/voxygen/shaders/include/light.glsl index 2b9d2fc118..d5021a1615 100644 --- a/assets/voxygen/shaders/include/light.glsl +++ b/assets/voxygen/shaders/include/light.glsl @@ -140,15 +140,14 @@ float lights_at(vec3 wpos, vec3 wnorm, vec3 /*cam_to_frag*/view_dir, vec3 mu, ve float distance_2 = dot(difference, difference); // float strength = attenuation_strength(difference);// pow(attenuation_strength(difference), 0.6); - // // NOTE: This normalizes strength to 1.0 at the center of the point source. - // float strength = 1.0 / (1.0 + distance_2); + // NOTE: This normalizes strength to 0.25 at the center of the point source. float strength = 1.0 / (4 + distance_2); // Multiply the vec3 only once const float PI = 3.1415926535897932384626433832795; const float PI_2 = 2 * PI; float square_factor = /*2.0 * PI_2 * *//*2.0 * */L.light_col.a; - vec3 color = /*srgb_to_linear*/L.light_col.rgb * vec3(1, 1, 1); + vec3 color = /*srgb_to_linear*/L.light_col.rgb; // // Only access the array once // Shadow S = shadows[i]; diff --git a/assets/voxygen/shaders/particle-frag.glsl b/assets/voxygen/shaders/particle-frag.glsl index e0300606a6..ad4152bce3 100644 --- a/assets/voxygen/shaders/particle-frag.glsl +++ b/assets/voxygen/shaders/particle-frag.glsl @@ -71,6 +71,7 @@ void main() { max_light += lights_at(f_pos, f_norm, view_dir, k_a, k_d, k_s, alpha, emitted_light, reflected_light); + // Allow particles to glow at night // TODO: Not this emitted_light += max(f_col.rgb - 1.0, vec3(0)); diff --git a/voxygen/src/scene/particle.rs b/voxygen/src/scene/particle.rs index 3319a073db..407e2d4ef2 100644 --- a/voxygen/src/scene/particle.rs +++ b/voxygen/src/scene/particle.rs @@ -282,82 +282,85 @@ impl ParticleMgr { (e.floor() as i32).div_euclid(sz as i32) }); - type BoiFn<'a> = fn(&'a BlocksOfInterest) -> &'a [Vec3]; - // blocks, chunk range, emission density, lifetime, particle mode, condition - // - // - blocks: the function to select the blocks of interest that we should emit - // from - // - chunk range: the range, in chunks, that the particles should be generated - // in from the player - // - emission density: the density, per block per second, of the generated - // particles - // - lifetime: the number of seconds that each particle should live for - // - particle mode: the visual mode of the generated particle - // - Condition required for emissions - let particles: &[(BoiFn, usize, f32, f32, ParticleMode, fn(&SceneData) -> bool)] = &[ - ( - |boi| &boi.leaves, - 4, - 0.001, - 30.0, - ParticleMode::Leaf, - |_| true, - ), - ( - |boi| &boi.embers, - 2, - 20.0, - 0.25, - ParticleMode::CampfireFire, - |_| true, - ), - ( - |boi| &boi.embers, - 8, - 3.0, - 40.0, - ParticleMode::CampfireSmoke, - |_| true, - ), - ( - |boi| &boi.reeds, - 6, - 0.004, - 40.0, - ParticleMode::Firefly, - |sd| sd.state.get_day_period().is_dark(), - ), - ( - |boi| &boi.flowers, - 5, - 0.002, - 40.0, - ParticleMode::Firefly, - |sd| sd.state.get_day_period().is_dark(), - ), - ( - |boi| &boi.beehives, - 3, - 0.5, - 30.0, - ParticleMode::Bee, - |sd| sd.state.get_day_period().is_light(), - ), + struct BlockParticles<'a> { + // The function to select the blocks of interest that we should emit from + blocks: fn(&'a BlocksOfInterest) -> &'a [Vec3], + // The range, in chunks, that the particles should be generated in from the player + range: usize, + // The emission rate, per block per second, of the generated particles + rate: f32, + // The number of seconds that each particle should live for + lifetime: f32, + // The visual mode of the generated particle + mode: ParticleMode, + // Condition that must be true + cond: fn(&SceneData) -> bool, + } + + let particles: &[BlockParticles] = &[ + BlockParticles { + blocks: |boi| &boi.leaves, + range: 4, + rate: 0.001, + lifetime: 30.0, + mode: ParticleMode::Leaf, + cond: |_| true, + }, + BlockParticles { + blocks: |boi| &boi.embers, + range: 2, + rate: 20.0, + lifetime: 0.25, + mode: ParticleMode::CampfireFire, + cond: |_| true, + }, + BlockParticles { + blocks: |boi| &boi.embers, + range: 8, + rate: 3.0, + lifetime: 40.0, + mode: ParticleMode::CampfireSmoke, + cond: |_| true, + }, + BlockParticles { + blocks: |boi| &boi.reeds, + range: 6, + rate: 0.004, + lifetime: 40.0, + mode: ParticleMode::Firefly, + cond: |sd| sd.state.get_day_period().is_dark(), + }, + BlockParticles { + blocks: |boi| &boi.flowers, + range: 5, + rate: 0.002, + lifetime: 40.0, + mode: ParticleMode::Firefly, + cond: |sd| sd.state.get_day_period().is_dark(), + }, + BlockParticles { + blocks: |boi| &boi.beehives, + range: 3, + rate: 0.5, + lifetime: 30.0, + mode: ParticleMode::Bee, + cond: |sd| sd.state.get_day_period().is_light(), + }, ]; let mut rng = thread_rng(); - for (get_blocks, range, rate, dur, mode, cond) in particles.iter() { - if !cond(scene_data) { + for particles in particles.iter() { + if !(particles.cond)(scene_data) { continue; } - for offset in Spiral2d::new().take((*range * 2 + 1).pow(2)) { + for offset in Spiral2d::new().take((particles.range * 2 + 1).pow(2)) { let chunk_pos = player_chunk + offset; terrain.get(chunk_pos).map(|chunk_data| { - let blocks = get_blocks(&chunk_data.blocks_of_interest); + let blocks = (particles.blocks)(&chunk_data.blocks_of_interest); - let avg_particles = dt * blocks.len() as f32 * *rate; + let avg_particles = dt * blocks.len() as f32 * particles.rate; let particle_count = avg_particles.trunc() as usize + (rng.gen::() < avg_particles.fract()) as usize; @@ -368,9 +371,9 @@ impl ParticleMgr { + blocks.choose(&mut rng).copied().unwrap(); // Can't fail Particle::new( - Duration::from_secs_f32(*dur), + Duration::from_secs_f32(particles.lifetime), time, - *mode, + particles.mode, block_pos.map(|e: i32| e as f32 + rng.gen::()), ) })