mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added lightning
This commit is contained in:
parent
622b67d24e
commit
4531a4e3f9
@ -1169,5 +1169,11 @@
|
||||
],
|
||||
threshold: 1.0,
|
||||
),
|
||||
Lightning: (
|
||||
files: [
|
||||
"voxygen.audio.sfx.ambient.lightning_1",
|
||||
],
|
||||
threshold: 1.0,
|
||||
),
|
||||
}
|
||||
)
|
||||
|
BIN
assets/voxygen/audio/sfx/ambient/lightning_1.ogg
(Stored with Git LFS)
Normal file
BIN
assets/voxygen/audio/sfx/ambient/lightning_1.ogg
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -110,7 +110,7 @@ void main() {
|
||||
vec3 wpos = cam_pos.xyz + dir * wpos_dist;
|
||||
|
||||
float density = rain_density * rain_occlusion_at(wpos);
|
||||
if (fract(hash(vec4(floor(wall_pos.xyz), 0))) > density) { continue; }
|
||||
if (fract(hash(vec4(floor(wall_pos.xyz), 0))) >= density) { continue; }
|
||||
|
||||
if (wpos_dist > dist) { break; }
|
||||
if (length((fract(wall_pos.xz) - 0.5)) < 0.1 + pow(max(0.0, wpos_dist - (dist - 0.25)) / 0.25, 4.0) * 0.2) {
|
||||
|
@ -300,7 +300,7 @@ vec3 get_cloud_color(vec3 surf_color, vec3 dir, vec3 origin, const float time_of
|
||||
};
|
||||
float h = max(0.0, min(pos.z, 900.0 - pos.z) / 450.0);
|
||||
float rain = rain_density_at(pos.xy) * pow(h, 0.1);
|
||||
|
||||
|
||||
float sun = sun_access * get_sun_brightness();
|
||||
float energy = pow(rain * sun * min(cdist / 500.0, 1.0), 2.0) * 0.4;
|
||||
|
||||
|
@ -19,6 +19,7 @@ layout(std140, set = 0, binding = 0) uniform u_globals {
|
||||
uvec4 medium;
|
||||
ivec4 select_pos;
|
||||
vec4 gamma_exposure;
|
||||
vec4 last_lightning;
|
||||
float ambiance;
|
||||
// 0 - FirstPerson
|
||||
// 1 - ThirdPerson
|
||||
|
@ -431,13 +431,31 @@ float get_sun_diffuse2(DirectionalLight sun_info, DirectionalLight moon_info, ve
|
||||
}
|
||||
#endif
|
||||
|
||||
float time_since_lightning = tick.x - last_lightning.w;
|
||||
vec3 lightning = vec3(0.0);
|
||||
if (time_since_lightning < 5.0) {
|
||||
vec3 diff = wpos + focus_off.xyz - (last_lightning.xyz + vec3(0, 0, 250));
|
||||
float dist = length(diff);
|
||||
lightning = vec3(0.5, 0.8, 1.0)
|
||||
// Strength
|
||||
* 1000000
|
||||
// Flash
|
||||
* max(0.0, 1.0 - time_since_lightning * 1.0)
|
||||
// Reverb
|
||||
* max(sin(time_of_day.x * 0.4), 0.0)
|
||||
// Direction
|
||||
* (dot(norm, diff / dist) + 1.0)
|
||||
// Attenuation
|
||||
/ pow(50.0 + dist, 2);
|
||||
}
|
||||
|
||||
reflected_light = R_t_r * (
|
||||
(1.0 - SUN_AMBIANCE) * sun_chroma * sun_shadow * (light_reflection_factor(norm, dir, sun_dir, k_d, k_s, alpha, voxel_norm, voxel_lighting) /*+
|
||||
light_reflection_factor(norm, dir, normalize(sun_dir + vec3(0.0, 0.1, 0.0)), k_d, k_s, alpha) +
|
||||
light_reflection_factor(norm, dir, normalize(sun_dir - vec3(0.0, 0.1, 0.0)), k_d, k_s, alpha)*/) +
|
||||
(1.0 - MOON_AMBIANCE) * moon_chroma * moon_shadow * 1.0 * /*4.0 * */light_reflection_factor(norm, dir, moon_dir, k_d, k_s, alpha, voxel_norm, voxel_lighting) +
|
||||
emission
|
||||
);
|
||||
) + lightning;
|
||||
|
||||
/* light = sun_chroma + moon_chroma + PERSISTENT_AMBIANCE;
|
||||
diffuse_light =
|
||||
|
@ -27,6 +27,9 @@ pub enum Outcome {
|
||||
is_attack: bool,
|
||||
reagent: Option<Reagent>, // How can we better define this?
|
||||
},
|
||||
Lightning {
|
||||
pos: Vec3<f32>,
|
||||
},
|
||||
ProjectileShot {
|
||||
pos: Vec3<f32>,
|
||||
body: comp::Body,
|
||||
@ -99,6 +102,8 @@ impl Outcome {
|
||||
pub fn get_pos(&self) -> Option<Vec3<f32>> {
|
||||
match self {
|
||||
Outcome::Explosion { pos, .. }
|
||||
// TODO: Include this, but allow it to be sent to clients when outside of the VD
|
||||
// | Outcome::Lightning { pos }
|
||||
| Outcome::ProjectileShot { pos, .. }
|
||||
| Outcome::ProjectileHit { pos, .. }
|
||||
| Outcome::Beam { pos, .. }
|
||||
@ -113,6 +118,7 @@ impl Outcome {
|
||||
Outcome::BreakBlock { pos, .. } => Some(pos.map(|e| e as f32 + 0.5)),
|
||||
Outcome::ExpChange { .. }
|
||||
| Outcome::ComboChange { .. }
|
||||
| Outcome::Lightning { .. }
|
||||
| Outcome::SkillPointGain { .. } => None,
|
||||
}
|
||||
}
|
||||
|
@ -1,9 +1,12 @@
|
||||
use common::{
|
||||
event::EventBus,
|
||||
grid::Grid,
|
||||
outcome::Outcome,
|
||||
resources::TimeOfDay,
|
||||
weather::{Weather, WeatherGrid, CELL_SIZE, CHUNKS_PER_CELL},
|
||||
};
|
||||
use noise::{NoiseFn, SuperSimplex, Turbulence};
|
||||
use rand::prelude::*;
|
||||
use vek::*;
|
||||
use world::World;
|
||||
|
||||
@ -20,6 +23,7 @@ struct WeatherZone {
|
||||
|
||||
struct CellConsts {
|
||||
humidity: f32,
|
||||
alt: f32,
|
||||
}
|
||||
|
||||
pub struct WeatherSim {
|
||||
@ -49,8 +53,13 @@ impl WeatherSim {
|
||||
}
|
||||
}
|
||||
let average_humid = humid_sum / (CHUNKS_PER_CELL * CHUNKS_PER_CELL) as f32;
|
||||
let humidity = average_humid.powf(0.2).min(1.0);
|
||||
CellConsts { humidity }
|
||||
CellConsts {
|
||||
humidity: average_humid.powf(0.2).min(1.0),
|
||||
alt: world
|
||||
.sim()
|
||||
.get_alt_approx(cell_to_wpos_center(p.map(|e| e as i32)))
|
||||
.unwrap_or(world::CONFIG.sea_level),
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>(),
|
||||
),
|
||||
@ -82,7 +91,12 @@ impl WeatherSim {
|
||||
}
|
||||
|
||||
// Time step is cell size / maximum wind speed
|
||||
pub fn tick(&mut self, time_of_day: &TimeOfDay, out: &mut WeatherGrid) {
|
||||
pub fn tick(
|
||||
&mut self,
|
||||
time_of_day: &TimeOfDay,
|
||||
outcomes: &EventBus<Outcome>,
|
||||
out: &mut WeatherGrid,
|
||||
) {
|
||||
let time = time_of_day.0;
|
||||
|
||||
let base_nz = Turbulence::new(
|
||||
@ -125,6 +139,12 @@ impl WeatherSim {
|
||||
rain_nz.get((spos + 1.0).into_array()).powi(3) as f32,
|
||||
) * 200.0
|
||||
* (1.0 - pressure);
|
||||
|
||||
if cell.rain > 0.02 && cell.cloud > 0.05 && thread_rng().gen_bool(0.01) {
|
||||
outcomes.emit_now(Outcome::Lightning {
|
||||
pos: wpos.map(|e| e as f32).with_z(self.consts[point].alt),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use common::{resources::TimeOfDay, weather::WeatherGrid};
|
||||
use common::{event::EventBus, outcome::Outcome, resources::TimeOfDay, weather::WeatherGrid};
|
||||
use common_ecs::{Origin, Phase, System};
|
||||
use specs::{Read, Write, WriteExpect};
|
||||
use specs::{Read, ReadExpect, Write, WriteExpect};
|
||||
|
||||
use crate::sys::SysScheduler;
|
||||
|
||||
@ -15,6 +15,7 @@ impl<'a> System<'a> for Sys {
|
||||
WriteExpect<'a, WeatherSim>,
|
||||
WriteExpect<'a, WeatherGrid>,
|
||||
Write<'a, SysScheduler<Self>>,
|
||||
ReadExpect<'a, EventBus<Outcome>>,
|
||||
);
|
||||
|
||||
const NAME: &'static str = "weather::tick";
|
||||
@ -23,13 +24,13 @@ impl<'a> System<'a> for Sys {
|
||||
|
||||
fn run(
|
||||
_job: &mut common_ecs::Job<Self>,
|
||||
(game_time, mut sim, mut grid, mut scheduler): Self::SystemData,
|
||||
(game_time, mut sim, mut grid, mut scheduler, outcomes): Self::SystemData,
|
||||
) {
|
||||
if scheduler.should_run() {
|
||||
if grid.size() != sim.size() {
|
||||
*grid = WeatherGrid::new(sim.size());
|
||||
}
|
||||
sim.tick(&game_time, &mut grid);
|
||||
sim.tick(&game_time, &outcomes, &mut grid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -190,6 +190,7 @@ pub enum SfxEvent {
|
||||
PoiseChange(PoiseState),
|
||||
GroundSlam,
|
||||
Utterance(UtteranceKind, VoiceKind),
|
||||
Lightning,
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone, Debug, PartialEq, Deserialize, Hash, Eq)]
|
||||
@ -432,6 +433,16 @@ impl SfxMgr {
|
||||
underwater,
|
||||
);
|
||||
},
|
||||
Outcome::Lightning { pos } => {
|
||||
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::Lightning);
|
||||
// TODO: Don't use UI sfx, add a way to control position falloff
|
||||
audio.emit_ui_sfx(
|
||||
sfx_trigger_item,
|
||||
Some(
|
||||
(1.0 - pos.distance(audio.listener.pos) / 10_000.0).clamped(0.0, 1.0) * 3.0,
|
||||
),
|
||||
);
|
||||
},
|
||||
Outcome::GroundSlam { pos, .. } => {
|
||||
let sfx_trigger_item = triggers.get_key_value(&SfxEvent::GroundSlam);
|
||||
audio.emit_sfx(sfx_trigger_item, *pos, Some(2.0), underwater);
|
||||
|
@ -64,6 +64,7 @@ pub struct Globals {
|
||||
medium: [u32; 4],
|
||||
select_pos: [i32; 4],
|
||||
gamma_exposure: [f32; 4],
|
||||
last_lightning: [f32; 4],
|
||||
ambiance: f32,
|
||||
cam_mode: u32,
|
||||
sprite_render_distance: f32,
|
||||
@ -108,6 +109,7 @@ impl Globals {
|
||||
select_pos: Option<Vec3<i32>>,
|
||||
gamma: f32,
|
||||
exposure: f32,
|
||||
last_lightning: (Vec3<f32>, f64),
|
||||
ambiance: f32,
|
||||
cam_mode: CameraMode,
|
||||
sprite_render_distance: f32,
|
||||
@ -156,6 +158,10 @@ impl Globals {
|
||||
.unwrap_or_else(Vec4::zero)
|
||||
.into_array(),
|
||||
gamma_exposure: [gamma, exposure, 0.0, 0.0],
|
||||
last_lightning: last_lightning
|
||||
.0
|
||||
.with_w(last_lightning.1 as f32)
|
||||
.into_array(),
|
||||
ambiance: ambiance.clamped(0.0, 1.0),
|
||||
cam_mode: cam_mode as u32,
|
||||
sprite_render_distance,
|
||||
@ -202,6 +208,7 @@ impl Default for Globals {
|
||||
None,
|
||||
1.0,
|
||||
1.0,
|
||||
(Vec3::zero(), -1000.0),
|
||||
1.0,
|
||||
CameraMode::ThirdPerson,
|
||||
250.0,
|
||||
|
@ -108,6 +108,7 @@ pub struct Scene {
|
||||
ambient_mgr: AmbientMgr,
|
||||
|
||||
integrated_rain_vel: f32,
|
||||
last_lightning: Option<(Vec3<f32>, f64)>,
|
||||
}
|
||||
|
||||
pub struct SceneData<'a> {
|
||||
@ -325,6 +326,7 @@ impl Scene {
|
||||
ambience: ambient::load_ambience_items(),
|
||||
},
|
||||
integrated_rain_vel: 0.0,
|
||||
last_lightning: None,
|
||||
}
|
||||
}
|
||||
|
||||
@ -426,6 +428,9 @@ impl Scene {
|
||||
.handle_outcome(outcome, audio, scene_data.client, underwater);
|
||||
|
||||
match outcome {
|
||||
Outcome::Lightning { pos } => {
|
||||
self.last_lightning = Some((*pos, scene_data.state.get_time()));
|
||||
},
|
||||
Outcome::Explosion {
|
||||
pos,
|
||||
power,
|
||||
@ -689,6 +694,7 @@ impl Scene {
|
||||
self.select_pos.map(|e| e - focus_off.map(|e| e as i32)),
|
||||
scene_data.gamma,
|
||||
scene_data.exposure,
|
||||
self.last_lightning.unwrap_or((Vec3::zero(), -1000.0)),
|
||||
scene_data.ambiance,
|
||||
self.camera.get_mode(),
|
||||
scene_data.sprite_render_distance as f32 - 20.0,
|
||||
|
@ -62,6 +62,17 @@ impl ParticleMgr {
|
||||
let mut rng = rand::thread_rng();
|
||||
|
||||
match outcome {
|
||||
Outcome::Lightning { pos } => {
|
||||
self.particles.resize_with(self.particles.len() + 400, || {
|
||||
Particle::new_directed(
|
||||
Duration::from_secs_f32(rng.gen_range(2.0..3.0)),
|
||||
time,
|
||||
ParticleMode::GunPowderSpark,
|
||||
*pos + Vec3::new(0.0, 0.0, rng.gen_range(250.0..1500.0)),
|
||||
*pos,
|
||||
)
|
||||
});
|
||||
},
|
||||
Outcome::Explosion {
|
||||
pos,
|
||||
power,
|
||||
|
@ -273,6 +273,7 @@ impl Scene {
|
||||
None,
|
||||
scene_data.gamma,
|
||||
scene_data.exposure,
|
||||
(Vec3::zero(), -1000.0),
|
||||
scene_data.ambiance,
|
||||
self.camera.get_mode(),
|
||||
250.0,
|
||||
|
Loading…
Reference in New Issue
Block a user