diff --git a/game/graphics/opengl_renderer/foreground/Merc2.cpp b/game/graphics/opengl_renderer/foreground/Merc2.cpp index 0e70c6b933..01807731fb 100644 --- a/game/graphics/opengl_renderer/foreground/Merc2.cpp +++ b/game/graphics/opengl_renderer/foreground/Merc2.cpp @@ -10,7 +10,8 @@ Merc2::Merc2(const std::string& name, BucketId my_id) : BucketRenderer(name, my_ glGenBuffers(1, &m_bones_buffer); glBindBuffer(GL_UNIFORM_BUFFER, m_bones_buffer); - glBufferData(GL_UNIFORM_BUFFER, MAX_SHADER_BONE_VECTORS * sizeof(math::Vector4f), nullptr, + std::vector temp(MAX_SHADER_BONE_VECTORS * sizeof(math::Vector4f)); + glBufferData(GL_UNIFORM_BUFFER, MAX_SHADER_BONE_VECTORS * sizeof(math::Vector4f), temp.data(), GL_DYNAMIC_DRAW); glBindBuffer(GL_UNIFORM_BUFFER, 0); diff --git a/game/graphics/opengl_renderer/shaders/merc2.vert b/game/graphics/opengl_renderer/shaders/merc2.vert index 8b32b16ebc..b0b2663840 100644 --- a/game/graphics/opengl_renderer/shaders/merc2.vert +++ b/game/graphics/opengl_renderer/shaders/merc2.vert @@ -74,16 +74,21 @@ void main() { // transformed += -hmat2 * position_in.z; vec4 p = vec4(position_in, 1); - vec4 vtx_pos = -bones[mats[0]].X * p * weights_in[0] - -bones[mats[1]].X * p * weights_in[1] - -bones[mats[2]].X * p * weights_in[2]; + vec4 vtx_pos = -bones[mats[0]].X * p * weights_in[0]; + vec3 rotated_nrm = bones[mats[0]].R * normal_in * weights_in[0]; + + // game may send garbage bones if the weight is 0, don't let NaNs sneak in. + if (weights_in[1] > 0) { + vtx_pos += -bones[mats[1]].X * p * weights_in[1]; + rotated_nrm += bones[mats[1]].R * normal_in * weights_in[1]; + } + if (weights_in[2] > 0) { + vtx_pos += -bones[mats[2]].X * p * weights_in[2]; + rotated_nrm += bones[mats[2]].R * normal_in * weights_in[2]; + } vec4 transformed = perspective_matrix * vtx_pos; - vec3 rotated_nrm = bones[mats[0]].R * normal_in * weights_in[0] - + bones[mats[1]].R * normal_in * weights_in[1] - + bones[mats[2]].R * normal_in * weights_in[2]; - rotated_nrm = normalize(rotated_nrm); vec3 light_intensity = light_dir0 * rotated_nrm.x + light_dir1 * rotated_nrm.y + light_dir2 * rotated_nrm.z; light_intensity = max(light_intensity, vec3(0, 0, 0));