diff --git a/assets/voxygen/shaders/figure-vert.glsl b/assets/voxygen/shaders/figure-vert.glsl index b9fa68bf15..bc22f0c68c 100644 --- a/assets/voxygen/shaders/figure-vert.glsl +++ b/assets/voxygen/shaders/figure-vert.glsl @@ -2,11 +2,10 @@ #include -in vec3 v_pos; +in uint v_pos_norm; in vec3 v_norm; -in vec3 v_col; -in float v_ao; -in uint v_bone_idx; +in uint v_col; +in uint v_ao_bone; layout (std140) uniform u_locals { @@ -33,20 +32,27 @@ flat out vec3 f_norm; void main() { // Pre-calculate bone matrix - mat4 combined_mat = model_mat * bones[v_bone_idx].bone_mat; + uint bone_idx = (v_ao_bone >> 2) & 0x3Fu; + mat4 combined_mat = model_mat * bones[bone_idx].bone_mat; + + vec3 pos = vec3((uvec3(v_pos_norm) >> uvec3(0, 8, 16)) & uvec3(0xFFu)) - 128.0; f_pos = ( combined_mat * - vec4(v_pos, 1)).xyz; + vec4(pos, 1)).xyz; - f_col = v_col; + f_col = vec3((uvec3(v_col) >> uvec3(0, 8, 16)) & uvec3(0xFFu)) / 255.0; - f_ao = v_ao; + f_ao = float(v_ao_bone & 0x3u) / 4.0; + + // First 3 normals are negative, next 3 are positive + vec3 normals[6] = vec3[](vec3(-1,0,0), vec3(1,0,0), vec3(0,-1,0), vec3(0,1,0), vec3(0,0,-1), vec3(0,0,1)); + vec3 norm = normals[(v_pos_norm >> 24) & 0x7u]; // Calculate normal here rather than for each pixel in the fragment shader f_norm = normalize(( combined_mat * - vec4(v_norm, 0.0) + vec4(norm, 0.0) ).xyz); gl_Position = all_mat * vec4(f_pos, 1); diff --git a/voxygen/src/render/pipelines/figure.rs b/voxygen/src/render/pipelines/figure.rs index 2fa38cbc1d..d87edef5fb 100644 --- a/voxygen/src/render/pipelines/figure.rs +++ b/voxygen/src/render/pipelines/figure.rs @@ -11,11 +11,12 @@ use vek::*; gfx_defines! { vertex Vertex { - pos: [f32; 3] = "v_pos", - norm: [f32; 3] = "v_norm", - col: [f32; 3] = "v_col", - ao: f32 = "v_ao", - bone_idx: u8 = "v_bone_idx", + pos_norm: u32 = "v_pos_norm", + col: u32 = "v_col", + // BBBBBBAA + // B = Bone + // A = AO + ao_bone: u8 = "v_ao_bone", } constant Locals { @@ -46,17 +47,26 @@ gfx_defines! { impl Vertex { pub fn new(pos: Vec3, norm: Vec3, col: Rgb, ao: f32, bone_idx: u8) -> Self { + let norm_bits = if norm.x != 0.0 { + if norm.x < 0.0 { 0 } else { 1 } + } else if norm.y != 0.0 { + if norm.y < 0.0 { 2 } else { 3 } + } else { + if norm.z < 0.0 { 4 } else { 5 } + }; Self { - pos: pos.into_array(), - col: col.into_array(), - norm: norm.into_array(), - ao, - bone_idx, + pos_norm: pos + .map2(Vec3::new(0, 8, 16), |e, shift| ((e + 128.0) as u32) << shift) + .reduce_bitor() | (norm_bits << 24), + col: col + .map2(Rgb::new(0, 8, 16), |e, shift| ((e * 255.0) as u32) << shift) + .reduce_bitor(), + ao_bone: (bone_idx << 2) | ((ao * 3.9999) as u8), } } pub fn with_bone_idx(mut self, bone_idx: u8) -> Self { - self.bone_idx = bone_idx; + self.ao_bone = (self.ao_bone & 0b11) | (bone_idx << 2); self } } diff --git a/voxygen/src/render/pipelines/sprite.rs b/voxygen/src/render/pipelines/sprite.rs index 08d2004a18..f5ef6e8d2e 100644 --- a/voxygen/src/render/pipelines/sprite.rs +++ b/voxygen/src/render/pipelines/sprite.rs @@ -56,7 +56,9 @@ impl Vertex { Self { pos: pos.into_array(), - col: col.map2(Rgb::new(0, 8, 16), |e, shift| ((e * 255.0) as u32) << shift).reduce_bitor(), + col: col + .map2(Rgb::new(0, 8, 16), |e, shift| ((e * 255.0) as u32) << shift) + .reduce_bitor(), norm_ao: norm_bits | (((ao * 3.9999) as u32) << 3), } }