Add player-relative rain direction

This commit is contained in:
Treeco 2022-05-30 22:02:22 +01:00 committed by IsseW
parent fa589e915e
commit 0d21361e05
10 changed files with 57 additions and 35 deletions

View File

@ -101,10 +101,7 @@ void main() {
vec3 old_color = color.rgb;
// If this value is changed also change it in common/src/weather.rs
float fall_rate = 70.0;
dir.xy += wind_vel * dir.z / fall_rate;
dir = normalize(dir);
dir = (vec4(dir, 0) * rel_rain_dir_mat).xyz;
float z = (-1 / (abs(dir.z) - 1) - 1) * sign(dir.z);
vec2 dir_2d = normalize(dir.xy);
@ -119,7 +116,7 @@ void main() {
vec2 drop_density = vec2(30, 1);
vec2 rain_pos = (view_pos * rain_dist);
rain_pos += vec2(0, tick.x * fall_rate + cam_wpos.z);
rain_pos.y += integrated_rain_vel;
vec2 cell = floor(rain_pos * drop_density) / drop_density;
@ -144,7 +141,7 @@ void main() {
}
vec2 near_drop = cell + (vec2(0.5) + (vec2(hash(vec4(cell, 0, 0)), 0.5) - 0.5) * vec2(2, 0)) / drop_density;
vec2 drop_size = vec2(0.0008, 0.05);
vec2 drop_size = vec2(0.0008, 0.03);
float avg_alpha = (drop_size.x * drop_size.y) * 10 / 1;
float alpha = sign(max(1 - length((rain_pos - near_drop) / drop_size * 0.1), 0));
float light = sqrt(dot(old_color, vec3(1))) + (get_sun_brightness() + get_moon_brightness()) * 0.01;

View File

@ -19,7 +19,6 @@ layout(std140, set = 0, binding = 0) uniform u_globals {
uvec4 medium;
ivec4 select_pos;
vec4 gamma_exposure;
vec2 wind_vel;
float ambiance;
// 0 - FirstPerson
// 1 - ThirdPerson

View File

@ -12,6 +12,9 @@ layout (std140, set = 0, binding = 14)
uniform u_rain_occlusion {
mat4 occlusionMatrices;
mat4 occlusion_texture_mat;
mat4 rel_rain_dir_mat;
float integrated_rain_vel;
vec3 occlusion_dummy; // Fix alignment.
};
float rain_occlusion_at(in vec3 fragPos)

View File

@ -28,6 +28,9 @@ layout (std140, set = 0, binding = 14)
uniform u_rain_occlusion {
mat4 rainOcclusionMatrices;
mat4 texture_mat;
mat4 rel_rain_dir_mat;
float integrated_rain_vel;
vec3 occlusion_dummy; // Fix alignment.
};
/* Accurate packed shadow maps for many lights at once!

View File

@ -30,6 +30,9 @@ layout (std140, set = 0, binding = 14)
uniform u_rain_occlusion {
mat4 rainOcclusionMatrices;
mat4 texture_mat;
mat4 rel_rain_dir_mat;
float integrated_rain_vel;
vec3 occlusion_dummy; // Fix alignment.
};
/* Accurate packed shadow maps for many lights at once!

View File

@ -5,6 +5,8 @@ use vek::{Lerp, Vec2, Vec3};
use crate::{grid::Grid, terrain::TerrainChunkSize, vol::RectVolSize};
pub const FALL_RATE: f32 = 20.0;
/// Weather::default is Clear, 0 degrees C and no wind
#[derive(Debug, Clone, Copy, Serialize, Deserialize, Default)]
pub struct Weather {
@ -42,9 +44,7 @@ impl Weather {
// Get the rain direction for this weather
pub fn rain_dir(&self) -> Vec3<f32> {
// If this value is changed also change it in cloud-frag.glsl
const FALL_RATE: f32 = 70.0;
(-Vec3::unit_z() + self.wind / FALL_RATE).normalized()
(-Vec3::unit_z() + self.wind / (2.0 * FALL_RATE)).normalized()
}
}

View File

@ -64,12 +64,11 @@ pub struct Globals {
medium: [u32; 4],
select_pos: [i32; 4],
gamma_exposure: [f32; 4],
wind_vel: [f32; 2],
ambiance: f32,
cam_mode: u32,
sprite_render_distance: f32,
/// To keep 16-byte-aligned.
globals_dummy: f32,
// To keep 16-byte-aligned.
globals_dummy: [f32; 1],
}
#[repr(C)]
@ -110,8 +109,8 @@ impl Globals {
ambiance: f32,
cam_mode: CameraMode,
sprite_render_distance: f32,
wind_vel: Vec2<f32>,
) -> Self {
// dbg!(core::mem::size_of::<Self>() % 16);
Self {
view_mat: view_mat.into_col_arrays(),
proj_mat: proj_mat.into_col_arrays(),
@ -156,11 +155,10 @@ impl Globals {
.unwrap_or_else(Vec4::zero)
.into_array(),
gamma_exposure: [gamma, exposure, 0.0, 0.0],
wind_vel: [wind_vel.x, wind_vel.y],
ambiance: ambiance.clamped(0.0, 1.0),
cam_mode: cam_mode as u32,
sprite_render_distance,
globals_dummy: 0.0,
globals_dummy: [0.0; 1],
}
}
@ -206,7 +204,6 @@ impl Default for Globals {
1.0,
CameraMode::ThirdPerson,
250.0,
Vec2::zero(),
)
}
}

View File

@ -5,21 +5,32 @@ use bytemuck::{Pod, Zeroable};
use vek::*;
#[repr(C)]
#[derive(Copy, Clone, Debug, Zeroable, Pod)]
#[derive(Copy, Clone, Debug, Zeroable, Pod, Default)]
pub struct Locals {
shadow_matrices: [[f32; 4]; 4],
texture_mats: [[f32; 4]; 4],
rel_rain_dir_mat: [[f32; 4]; 4],
integrated_rain_vel: f32,
// To keep 16-byte-aligned.
occlusion_dummy: [f32; 3],
}
impl Locals {
pub fn new(shadow_mat: Mat4<f32>, texture_mat: Mat4<f32>) -> Self {
pub fn new(
shadow_mat: Mat4<f32>,
texture_mat: Mat4<f32>,
rel_rain_dir_mat: Mat4<f32>,
integrated_rain_vel: f32,
) -> Self {
// dbg!(core::mem::size_of::<Self>() % 16);
Self {
shadow_matrices: shadow_mat.into_col_arrays(),
texture_mats: texture_mat.into_col_arrays(),
rel_rain_dir_mat: rel_rain_dir_mat.into_col_arrays(),
integrated_rain_vel,
occlusion_dummy: [0.0; 3],
}
}
pub fn default() -> Self { Self::new(Mat4::identity(), Mat4::identity()) }
}
pub type BoundLocals = Bound<Consts<Locals>>;

View File

@ -103,6 +103,8 @@ pub struct Scene {
pub sfx_mgr: SfxMgr,
music_mgr: MusicMgr,
ambient_mgr: AmbientMgr,
integrated_rain_vel: f32,
}
pub struct SceneData<'a> {
@ -319,6 +321,7 @@ impl Scene {
ambient_mgr: AmbientMgr {
ambience: ambient::load_ambience_items(),
},
integrated_rain_vel: 0.0,
}
}
@ -475,11 +478,18 @@ impl Scene {
// Get player position.
let ecs = scene_data.state.ecs();
let dt = ecs.fetch::<DeltaTime>().0;
let player_pos = ecs
.read_storage::<comp::Pos>()
.get(scene_data.player_entity)
.map_or(Vec3::zero(), |pos| pos.0);
let player_vel = ecs
.read_storage::<comp::Vel>()
.get(scene_data.player_entity)
.map_or(Vec3::zero(), |vel| vel.0);
let player_rolling = ecs
.read_storage::<comp::CharacterState>()
.get(scene_data.player_entity)
@ -538,11 +548,8 @@ impl Scene {
};
// Tick camera for interpolation.
self.camera.update(
scene_data.state.get_time(),
scene_data.state.get_delta_time(),
scene_data.mouse_smoothing,
);
self.camera
.update(scene_data.state.get_time(), dt, scene_data.mouse_smoothing);
// Compute camera matrices.
self.camera.compute_dependents(&*scene_data.state.terrain());
@ -613,7 +620,6 @@ impl Scene {
renderer.update_consts(&mut self.data.lights, lights);
// Update event lights
let dt = ecs.fetch::<DeltaTime>().0;
self.event_lights.drain_filter(|el| {
el.timeout -= dt;
el.timeout <= 0.0
@ -688,10 +694,6 @@ impl Scene {
scene_data.ambiance,
self.camera.get_mode(),
scene_data.sprite_render_distance as f32 - 20.0,
client
.state()
.weather_at(focus_off.xy() + cam_pos.xy())
.wind,
)]);
renderer.update_clouds_locals(CloudsLocals::new(proj_mat_inv, view_mat_inv));
renderer.update_postprocess_locals(PostProcessLocals::new(proj_mat_inv, view_mat_inv));
@ -1003,13 +1005,21 @@ impl Scene {
.max_weather_near(focus_off.xy() + cam_pos.xy());
if weather.rain > 0.0 {
let weather = client.state().weather_at(focus_off.xy() + cam_pos.xy());
let rain_dir = math::Vec3::from(weather.rain_dir());
let rain_dir = weather.rain_dir();
let rain_view_mat = math::Mat4::look_at_rh(look_at, look_at + rain_dir, up);
let rain_vel = rain_dir * common::weather::FALL_RATE - player_vel;
self.integrated_rain_vel += rain_vel.magnitude() * dt;
let rel_rain_dir_mat = Mat4::rotation_from_to_3d(-Vec3::unit_z(), rain_vel);
let (shadow_mat, texture_mat) =
directed_mats(rain_view_mat, rain_dir, &visible_occlusion_volume);
directed_mats(rain_view_mat, rain_dir.into(), &visible_occlusion_volume);
let rain_occlusion_locals = RainOcclusionLocals::new(shadow_mat, texture_mat);
let rain_occlusion_locals = RainOcclusionLocals::new(
shadow_mat,
texture_mat,
rel_rain_dir_mat,
self.integrated_rain_vel,
);
renderer.update_consts(&mut self.data.rain_occlusion_mats, &[rain_occlusion_locals]);
}

View File

@ -276,7 +276,6 @@ impl Scene {
scene_data.ambiance,
self.camera.get_mode(),
250.0,
Vec2::zero(),
)]);
self.figure_model_cache