From 5e794b73baca68c557093ebcd0b4a1cecdd41659 Mon Sep 17 00:00:00 2001 From: ackwell Date: Wed, 17 Jan 2024 01:40:19 +1100 Subject: [PATCH] Consider normal morphs for morphed bitangent calculations --- .../Import/Models/Import/VertexAttribute.cs | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/Penumbra/Import/Models/Import/VertexAttribute.cs b/Penumbra/Import/Models/Import/VertexAttribute.cs index 5008b58e..bbf49bcf 100644 --- a/Penumbra/Import/Models/Import/VertexAttribute.cs +++ b/Penumbra/Import/Models/Import/VertexAttribute.cs @@ -251,11 +251,11 @@ public class VertexAttribute } var normals = normalAccessor.AsVector3Array(); - var values = accessors.TryGetValue("TANGENT", out var accessor) + var tangents = accessors.TryGetValue("TANGENT", out var accessor) ? accessor.AsVector4Array() : CalculateTangents(accessors, indices, normals); - if (values == null) + if (tangents == null) { Penumbra.Log.Warning("No tangents available for sub-mesh. This could lead to incorrect lighting, or mismatched vertex attributes."); return null; @@ -269,22 +269,30 @@ public class VertexAttribute }; // Per glTF specification, TANGENT morph values are stored as vec3, with the W component always considered to be 0. - var morphValues = morphAccessors + var tangentMorphValues = morphAccessors + .Select(a => a.GetValueOrDefault("TANGENT")?.AsVector3Array()) + .ToArray(); + + var normalMorphValues = morphAccessors .Select(a => a.GetValueOrDefault("TANGENT")?.AsVector3Array()) .ToArray(); return new VertexAttribute( element, - index => BuildBitangent(values[index], normals[index]), + index => BuildBitangent(tangents[index], normals[index]), buildMorph: (morphIndex, vertexIndex) => { - var value = values[vertexIndex]; + var tangent = tangents[vertexIndex]; + var tangentDelta = tangentMorphValues[morphIndex]?[vertexIndex]; + if (tangentDelta != null) + tangent += new Vector4(tangentDelta.Value, 0); - var delta = morphValues[morphIndex]?[vertexIndex]; - if (delta != null) - value += new Vector4(delta.Value, 0); + var normal = normals[vertexIndex]; + var normalDelta = normalMorphValues[morphIndex]?[vertexIndex]; + if (normalDelta != null) + normal += normalDelta.Value; - return BuildBitangent(value, normals[vertexIndex]); + return BuildBitangent(tangent, normal); } ); }