Consider normal morphs for morphed bitangent calculations

This commit is contained in:
ackwell 2024-01-17 01:40:19 +11:00
parent ea04cc554f
commit 5e794b73ba

View file

@ -251,11 +251,11 @@ public class VertexAttribute
} }
var normals = normalAccessor.AsVector3Array(); var normals = normalAccessor.AsVector3Array();
var values = accessors.TryGetValue("TANGENT", out var accessor) var tangents = accessors.TryGetValue("TANGENT", out var accessor)
? accessor.AsVector4Array() ? accessor.AsVector4Array()
: CalculateTangents(accessors, indices, normals); : 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."); Penumbra.Log.Warning("No tangents available for sub-mesh. This could lead to incorrect lighting, or mismatched vertex attributes.");
return null; 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. // 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()) .Select(a => a.GetValueOrDefault("TANGENT")?.AsVector3Array())
.ToArray(); .ToArray();
return new VertexAttribute( return new VertexAttribute(
element, element,
index => BuildBitangent(values[index], normals[index]), index => BuildBitangent(tangents[index], normals[index]),
buildMorph: (morphIndex, vertexIndex) => 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]; var normal = normals[vertexIndex];
if (delta != null) var normalDelta = normalMorphValues[morphIndex]?[vertexIndex];
value += new Vector4(delta.Value, 0); if (normalDelta != null)
normal += normalDelta.Value;
return BuildBitangent(value, normals[vertexIndex]); return BuildBitangent(tangent, normal);
} }
); );
} }