From 85c3d76878579520f2a42f4688f5219c8142b4b4 Mon Sep 17 00:00:00 2001 From: water111 <48171810+water111@users.noreply.github.com> Date: Fri, 24 Jun 2022 18:39:26 -0400 Subject: [PATCH] [merc2] guard against nans in bones (#1549) * [merc2] guard against bones in nans * zero out bone buffer, just to be safe --- .../opengl_renderer/foreground/Merc2.cpp | 3 ++- .../opengl_renderer/shaders/merc2.vert | 19 ++++++++++++------- 2 files changed, 14 insertions(+), 8 deletions(-) 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));