diff --git a/assets/voxygen/shaders/sprite-vert.glsl b/assets/voxygen/shaders/sprite-vert.glsl index 3c680614ae..394abdfb74 100644 --- a/assets/voxygen/shaders/sprite-vert.glsl +++ b/assets/voxygen/shaders/sprite-vert.glsl @@ -6,8 +6,12 @@ in vec3 v_pos; in vec3 v_norm; in vec3 v_col; -in vec3 inst_pos; +in vec4 inst_mat0; +in vec4 inst_mat1; +in vec4 inst_mat2; +in vec4 inst_mat3; in vec3 inst_col; +in float inst_wind_sway; out vec3 f_pos; flat out vec3 f_norm; @@ -17,10 +21,20 @@ out float f_light; const float SCALE = 1.0 / 11.0; void main() { - f_pos = inst_pos + v_pos * SCALE; + mat4 inst_mat; + inst_mat[0] = inst_mat0; + inst_mat[1] = inst_mat1; + inst_mat[2] = inst_mat2; + inst_mat[3] = inst_mat3; + + f_pos = (inst_mat * vec4(v_pos * SCALE, 1)).xyz; // Wind waving - f_pos += vec3(sin(tick.x * 1.7 + inst_pos.y * 0.2), sin(tick.x * 1.3 + inst_pos.x * 0.2), 0) * sin(v_pos.z * 0.03) * 0.5; + f_pos += inst_wind_sway * vec3( + sin(tick.x * 1.7 + f_pos.y * 0.2), + sin(tick.x * 1.3 + f_pos.x * 0.2), + 0.0 + ) * sin(v_pos.z * 0.03) * 0.5; f_norm = v_norm; diff --git a/voxygen/src/render/pipelines/sprite.rs b/voxygen/src/render/pipelines/sprite.rs index 4a6a94b30a..e6265c3757 100644 --- a/voxygen/src/render/pipelines/sprite.rs +++ b/voxygen/src/render/pipelines/sprite.rs @@ -1,5 +1,5 @@ use super::{ - super::{Pipeline, TgtColorFmt, TgtDepthFmt}, + super::{util::arr_to_mat, Pipeline, TgtColorFmt, TgtDepthFmt}, Globals, Light, }; use gfx::{ @@ -22,8 +22,12 @@ gfx_defines! { } vertex Instance { - inst_pos: [f32; 3] = "inst_pos", + inst_mat0: [f32; 4] = "inst_mat0", + inst_mat1: [f32; 4] = "inst_mat1", + inst_mat2: [f32; 4] = "inst_mat2", + inst_mat3: [f32; 4] = "inst_mat3", inst_col: [f32; 3] = "inst_col", + inst_wind_sway: f32 = "inst_wind_sway", } pipeline pipe { @@ -49,17 +53,22 @@ impl Vertex { } impl Instance { - pub fn new(inst_pos: Vec3, col: Rgb) -> Self { + pub fn new(mat: Mat4, col: Rgb, wind_sway: f32) -> Self { + let mat_arr = arr_to_mat(mat.into_col_array()); Self { - inst_pos: inst_pos.into_array(), + inst_mat0: mat_arr[0], + inst_mat1: mat_arr[1], + inst_mat2: mat_arr[2], + inst_mat3: mat_arr[3], inst_col: col.into_array(), + inst_wind_sway: wind_sway, } } } impl Default for Instance { fn default() -> Self { - Self::new(Vec3::zero(), Rgb::broadcast(1.0)) + Self::new(Mat4::identity(), Rgb::broadcast(1.0), 0.0) } } diff --git a/voxygen/src/scene/terrain.rs b/voxygen/src/scene/terrain.rs index ca5699cbf6..5267049e01 100644 --- a/voxygen/src/scene/terrain.rs +++ b/voxygen/src/scene/terrain.rs @@ -47,6 +47,19 @@ struct MeshWorkerResponse { started_tick: u64, } +struct SpriteConfig { + wind_sway: f32, // 1.0 is normal +} + +fn sprite_config_for(kind: BlockKind) -> Option { + match kind { + BlockKind::Wheat => Some(SpriteConfig { wind_sway: 1.0 }), + BlockKind::LongGrass => Some(SpriteConfig { wind_sway: 1.0 }), + BlockKind::Flowers => Some(SpriteConfig { wind_sway: 0.3 }), + _ => None, + } +} + /// Function executed by worker threads dedicated to chunk meshing. fn mesh_worker( pos: Vec2, @@ -73,16 +86,17 @@ fn mesh_worker( ) + Vec3::new(x, y, z); let kind = volume.get(wpos).unwrap_or(&Block::empty()).kind(); - match kind { - BlockKind::Wheat | BlockKind::LongGrass | BlockKind::Flowers => { - instances.entry(kind).or_insert_with(|| Vec::new()).push( - SpriteInstance::new( + + if let Some(cfg) = sprite_config_for(kind) { + instances.entry(kind).or_insert_with(|| Vec::new()).push( + SpriteInstance::new( + Mat4::identity().translated_3d( wpos.map(|e| e as f32) + Vec3::new(0.5, 0.5, 0.0), - Rgb::broadcast(1.0), ), - ) - } - _ => {} + Rgb::broadcast(1.0), + cfg.wind_sway, + ), + ); } } }