mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Make wind sway change according to weather wind velocity
This commit is contained in:
parent
873d3fb7a4
commit
f48e1ca951
@ -20,6 +20,7 @@ layout(std140, set = 0, binding = 0) uniform u_globals {
|
||||
ivec4 select_pos;
|
||||
vec4 gamma_exposure;
|
||||
vec4 last_lightning;
|
||||
vec2 wind_vel;
|
||||
float ambiance;
|
||||
// 0 - FirstPerson
|
||||
// 1 - ThirdPerson
|
||||
|
@ -53,6 +53,7 @@ const float SCALE = 1.0 / 11.0;
|
||||
const float SCALE_FACTOR = pow(SCALE, 1.3) * 0.2;
|
||||
|
||||
const float EXTRA_NEG_Z = 32768.0;
|
||||
const float VERT_EXTRA_NEG_XY = 128.0;
|
||||
const float VERT_EXTRA_NEG_Z = 128.0;
|
||||
const uint VERT_PAGE_SIZE = 256;
|
||||
|
||||
@ -74,6 +75,19 @@ vec4 nearest_entity(in vec3 sprite_pos, const float entity_radius_factor) {
|
||||
return closest;
|
||||
}
|
||||
|
||||
float wind_wave(float off, float scaling, float speed, float strength) {
|
||||
float aspeed = abs(speed);
|
||||
|
||||
// TODO: Right now, the wind model is pretty simplistic. This means that there is frequently no wind at all, which
|
||||
// looks bad. For now, we add a lower bound on the wind speed to keep things looking nice.
|
||||
strength = max(strength, 3.0);
|
||||
aspeed = max(aspeed, 3.0);
|
||||
|
||||
return (sin(tick.x * 0.75 * scaling * floor(aspeed) + off) * (1.0 - fract(aspeed))
|
||||
+ sin(tick.x * 0.75 * scaling * ceil(aspeed) + off) * fract(aspeed)) * abs(strength) * 0.5;
|
||||
//return sin(tick.x * 1.5 * scaling + off) + sin(tick.x * 0.35 * scaling + off);
|
||||
}
|
||||
|
||||
void main() {
|
||||
// Matrix to transform this sprite instance from model space to chunk space
|
||||
mat4 inst_mat;
|
||||
@ -94,7 +108,11 @@ void main() {
|
||||
uint v_atlas_pos = pos_atlas_pos_norm_ao.y;
|
||||
|
||||
// Expand the model vertex position bits into float values
|
||||
vec3 v_pos = vec3(v_pos_norm & 0xFFu, (v_pos_norm >> 8) & 0xFFu, float((v_pos_norm >> 16) & 0x0FFFu) - VERT_EXTRA_NEG_Z);
|
||||
vec3 v_pos = vec3(
|
||||
float(v_pos_norm & 0xFFu) - VERT_EXTRA_NEG_XY,
|
||||
float((v_pos_norm >> 8) & 0xFFu) - VERT_EXTRA_NEG_XY,
|
||||
float((v_pos_norm >> 16) & 0x0FFFu) - VERT_EXTRA_NEG_Z
|
||||
);
|
||||
|
||||
// Position of the sprite block in the chunk
|
||||
// Used for highlighting the selected sprite, and for opening doors
|
||||
@ -142,15 +160,16 @@ void main() {
|
||||
#endif
|
||||
|
||||
#ifndef EXPERIMENTAL_BAREMINIMUM
|
||||
// TODO: take wind_vel into account
|
||||
// Wind sway effect
|
||||
f_pos += model_wind_sway * vec3(
|
||||
sin(tick.x * 1.5 + f_pos.y * 0.1) * sin(tick.x * 0.35),
|
||||
sin(tick.x * 1.5 + f_pos.x * 0.1) * sin(tick.x * 0.25),
|
||||
0.0
|
||||
// NOTE: could potentially replace `v_pos.z * model_z_scale` with a calculation using `inst_chunk_pos` from below
|
||||
//) * pow(abs(v_pos.z * model_z_scale), 1.3) * SCALE_FACTOR;
|
||||
) * v_pos.z * model_z_scale * SCALE_FACTOR;
|
||||
f_pos.xy += (wind_vel * 0.1 + vec2(
|
||||
wind_wave(f_pos.y * 0.1, 0.9, wind_vel.x, wind_vel.y),
|
||||
wind_wave(f_pos.x * 0.1, 1.1, wind_vel.y, wind_vel.x)
|
||||
))
|
||||
* model_wind_sway
|
||||
//* mix(10.0, abs(v_pos.z), 1.0 / (1.0 + abs(v_pos.z) * 0.1))
|
||||
* v_pos.z
|
||||
* model_z_scale
|
||||
* SCALE_FACTOR;
|
||||
|
||||
if (model_wind_sway > 0.0) {
|
||||
vec2 center = sprite_pos.xy + 0.5;
|
||||
|
@ -700,16 +700,16 @@ Liana: Some((
|
||||
variations: [
|
||||
(
|
||||
model: "voxygen.voxel.sprite.lianas.liana-0",
|
||||
offset: (-4.0, -4.0, -88.0),
|
||||
offset: (-4.0, -4.0, -115.0),
|
||||
lod_axes: (0.0, 0.0, 0.5),
|
||||
),
|
||||
(
|
||||
model: "voxygen.voxel.sprite.lianas.liana-1",
|
||||
offset: (-4.0, -4.0, -55.0),
|
||||
offset: (-4.0, -4.0, -72.0),
|
||||
lod_axes: (0.0, 0.0, 0.5),
|
||||
),
|
||||
],
|
||||
wind_sway: 0.0,
|
||||
wind_sway: 0.5,
|
||||
)),
|
||||
// Velorite
|
||||
Velorite: Some((
|
||||
@ -1403,7 +1403,7 @@ SavannaBush: Some((
|
||||
lod_axes: (1.0, 1.0, 1.0),
|
||||
),
|
||||
],
|
||||
wind_sway: 0.1,
|
||||
wind_sway: 0.2,
|
||||
)),
|
||||
// Dead Bush
|
||||
DeadBush: Some((
|
||||
@ -1429,7 +1429,7 @@ DeadBush: Some((
|
||||
lod_axes: (1.0, 1.0, 1.0),
|
||||
),
|
||||
],
|
||||
wind_sway: 0.1,
|
||||
wind_sway: 0.2,
|
||||
)),
|
||||
// Blueberries
|
||||
// NOTE: Why are these commented out?
|
||||
@ -3049,7 +3049,7 @@ GiantKelp: Some((
|
||||
],
|
||||
wind_sway: 0.2,
|
||||
)),
|
||||
// Red Algae
|
||||
// Red Algae
|
||||
RedAlgae: None,
|
||||
// Underwater Vent
|
||||
UnderwaterVent: None,
|
||||
|
@ -43,7 +43,12 @@ impl Weather {
|
||||
// Get the rain velocity for this weather
|
||||
pub fn rain_vel(&self) -> Vec3<f32> {
|
||||
const FALL_RATE: f32 = 30.0;
|
||||
Vec3::new(self.wind.x, self.wind.y, -FALL_RATE)
|
||||
self.wind.with_z(-FALL_RATE)
|
||||
}
|
||||
|
||||
// Get the wind velocity for this weather
|
||||
pub fn wind_vel(&self) -> Vec2<f32> {
|
||||
self.wind
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,6 +122,7 @@ pub fn generate_mesh_base_vol_sprite<'a: 'b, 'b, V: 'a>(
|
||||
&'b mut Mesh<SpriteVertex>,
|
||||
bool,
|
||||
),
|
||||
offset: Vec3<f32>,
|
||||
) -> MeshGen<SpriteVertex, SpriteVertex, TerrainVertex, ()>
|
||||
where
|
||||
V: BaseVol<Vox = Cell> + ReadVol + SizedVol,
|
||||
@ -211,7 +212,7 @@ where
|
||||
// position, pos + mesh_delta, is guaranteed to fit in an f32).
|
||||
let mesh_delta = lower_bound.as_::<f32>();
|
||||
let create_opaque = |atlas_pos, pos: Vec3<f32>, norm, _meta| {
|
||||
SpriteVertex::new(atlas_pos, pos + mesh_delta, norm)
|
||||
SpriteVertex::new(atlas_pos, pos + offset + mesh_delta, norm)
|
||||
};
|
||||
|
||||
greedy.push(GreedyConfig {
|
||||
|
@ -65,11 +65,12 @@ pub struct Globals {
|
||||
select_pos: [i32; 4],
|
||||
gamma_exposure: [f32; 4],
|
||||
last_lightning: [f32; 4],
|
||||
wind_vel: [f32; 2],
|
||||
ambiance: f32,
|
||||
cam_mode: u32,
|
||||
sprite_render_distance: f32,
|
||||
// To keep 16-byte-aligned.
|
||||
globals_dummy: [f32; 1],
|
||||
globals_dummy: [f32; 3],
|
||||
}
|
||||
/// Make sure Globals is 16-byte-aligned.
|
||||
const _: () = assert!(core::mem::size_of::<Globals>() % 16 == 0);
|
||||
@ -110,6 +111,7 @@ impl Globals {
|
||||
gamma: f32,
|
||||
exposure: f32,
|
||||
last_lightning: (Vec3<f32>, f64),
|
||||
wind_vel: Vec2<f32>,
|
||||
ambiance: f32,
|
||||
cam_mode: CameraMode,
|
||||
sprite_render_distance: f32,
|
||||
@ -162,10 +164,11 @@ impl Globals {
|
||||
.0
|
||||
.with_w(last_lightning.1 as f32)
|
||||
.into_array(),
|
||||
wind_vel: wind_vel.into_array(),
|
||||
ambiance: ambiance.clamped(0.0, 1.0),
|
||||
cam_mode: cam_mode as u32,
|
||||
sprite_render_distance,
|
||||
globals_dummy: [0.0; 1],
|
||||
globals_dummy: [0.0; 3],
|
||||
}
|
||||
}
|
||||
|
||||
@ -209,6 +212,7 @@ impl Default for Globals {
|
||||
1.0,
|
||||
1.0,
|
||||
(Vec3::zero(), -1000.0),
|
||||
Vec2::zero(),
|
||||
1.0,
|
||||
CameraMode::ThirdPerson,
|
||||
250.0,
|
||||
|
@ -42,6 +42,7 @@ impl Vertex {
|
||||
// NOTE: Limit to 16 (x) × 16 (y) × 32 (z).
|
||||
#[allow(clippy::collapsible_else_if)]
|
||||
pub fn new(atlas_pos: Vec2<u16>, pos: Vec3<f32>, norm: Vec3<f32>) -> Self {
|
||||
const VERT_EXTRA_NEG_XY: i32 = 128;
|
||||
const VERT_EXTRA_NEG_Z: i32 = 128; // NOTE: change if number of bits changes below, also we might not need this if meshing always produces positives values for sprites (I have no idea)
|
||||
|
||||
#[allow(clippy::bool_to_int_with_if)]
|
||||
@ -59,8 +60,8 @@ impl Vertex {
|
||||
// | (((pos + EXTRA_NEG_Z).z.max(0.0).min((1 << 16) as f32) as u32) & 0xFFFF) << 12
|
||||
// | if meta { 1 } else { 0 } << 28
|
||||
// | (norm_bits & 0x7) << 29,
|
||||
pos_norm: ((pos.x as u32) & 0x00FF) // NOTE: temp hack, this doesn't need 8 bits
|
||||
| ((pos.y as u32) & 0x00FF) << 8
|
||||
pos_norm: (((pos.x as i32 + VERT_EXTRA_NEG_XY) & 0x00FF) as u32) // NOTE: temp hack, this doesn't need 8 bits
|
||||
| (((pos.y as i32 + VERT_EXTRA_NEG_XY) & 0x00FF) as u32) << 8
|
||||
| (((pos.z as i32 + VERT_EXTRA_NEG_Z).clamp(0, 1 << 12) as u32) & 0x0FFF) << 16
|
||||
| (norm_bits & 0x7) << 29,
|
||||
atlas_pos: ((atlas_pos.x as u32) & 0xFFFF) | ((atlas_pos.y as u32) & 0xFFFF) << 16,
|
||||
|
@ -111,6 +111,7 @@ pub struct Scene {
|
||||
ambient_mgr: AmbientMgr,
|
||||
|
||||
integrated_rain_vel: f32,
|
||||
wind_vel: Vec2<f32>,
|
||||
pub interpolated_time_of_day: Option<f64>,
|
||||
last_lightning: Option<(Vec3<f32>, f64)>,
|
||||
}
|
||||
@ -345,6 +346,7 @@ impl Scene {
|
||||
ambience: ambient::load_ambience_items(),
|
||||
},
|
||||
integrated_rain_vel: 0.0,
|
||||
wind_vel: Vec2::zero(),
|
||||
interpolated_time_of_day: None,
|
||||
last_lightning: None,
|
||||
}
|
||||
@ -783,6 +785,7 @@ impl Scene {
|
||||
scene_data.gamma,
|
||||
scene_data.exposure,
|
||||
self.last_lightning.unwrap_or((Vec3::zero(), -1000.0)),
|
||||
self.wind_vel,
|
||||
scene_data.ambiance,
|
||||
self.camera.get_mode(),
|
||||
scene_data.sprite_render_distance - 20.0,
|
||||
@ -1101,6 +1104,7 @@ impl Scene {
|
||||
let weather = client
|
||||
.state()
|
||||
.max_weather_near(focus_off.xy() + cam_pos.xy());
|
||||
self.wind_vel = weather.wind_vel();
|
||||
if weather.rain > RAIN_THRESHOLD {
|
||||
let weather = client.state().weather_at(focus_off.xy() + cam_pos.xy());
|
||||
let rain_vel = weather.rain_vel();
|
||||
|
@ -274,6 +274,7 @@ impl Scene {
|
||||
scene_data.gamma,
|
||||
scene_data.exposure,
|
||||
(Vec3::zero(), -1000.0),
|
||||
Vec2::zero(),
|
||||
scene_data.ambiance,
|
||||
self.camera.get_mode(),
|
||||
250.0,
|
||||
|
@ -515,6 +515,7 @@ impl SpriteRenderContext {
|
||||
generate_mesh_base_vol_sprite(
|
||||
Segment::from(&model.read().0).scaled_by(lod_scale),
|
||||
(greedy, sprite_mesh, false),
|
||||
offset.map(|e: f32| e.floor()) * lod_scale,
|
||||
);
|
||||
// Get the number of pages after the model was meshed
|
||||
let end_page_num = (sprite_mesh.vertices().len()
|
||||
@ -532,7 +533,7 @@ impl SpriteRenderContext {
|
||||
SpriteData {
|
||||
vert_pages: start_page_num as u32..end_page_num as u32,
|
||||
scale: sprite_scale,
|
||||
offset,
|
||||
offset: offset.map(|e| e.rem_euclid(1.0)),
|
||||
}
|
||||
});
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user