Tangent-related fixups in MeshAssimp.

Assimp's CalcTangentSpace deviates from de facto glTF 2.0 so we were
compensating for this with an unconditional fixup in MeshAssimp. However
the fixup should apply only when CalcTangentSpace is active, i.e. when
the model is missing tangents.

This makes it so that NormalTangentMirrorTest (has tangents) and
NormalTangentTest (needs tangents) both look reasonable.

I also noticed that MeshAssimp was inexplicably applying
aiProcess_CalcTangentSpace twice: once as a flag, and once as a
post-process. I removed the latter.

This will be fixed in the upcoming cgltf-based loader, which will
use our officially-sanctioned utility method in VertexBuffer.

See #528
This commit is contained in:
Philip Rideout
2019-02-20 12:17:37 -08:00
parent 9b5060bb1d
commit 84eb9547f5
3 changed files with 9 additions and 11 deletions

View File

@@ -648,8 +648,6 @@ bool MeshAssimp::setFromFile(Asset& asset, std::map<std::string, MaterialInstanc
// we only support triangles
aiProcess_Triangulate);
scene = importer.ApplyPostProcessing(aiProcess_CalcTangentSpace);
size_t index = importer.GetImporterIndex(asset.file.getExtension().c_str());
const aiImporterDesc* importerDesc = importer.GetImporterInfo(index);
bool isGLTF = importerDesc &&
@@ -842,12 +840,8 @@ void MeshAssimp::processNode(Asset& asset,
bitangent = normalize(cross(normal, float3{1.0, 0.0, 0.0}));
tangent = normalize(cross(normal, bitangent));
} else {
// In assimp, the CalcTangentsProcess algorithm generates tangents in
// the +U direction and bitangents in the +V direction, but the glTF
// conformance suite (see NormalTangentTest) reveals that bitangents
// should be flipped.
tangent = tangents[j];
bitangent = -bitangents[j];
bitangent = bitangents[j];
}
quatf q = filament::math::details::TMat33<float>::packTangentFrame({tangent, bitangent, normal});

View File

@@ -196,14 +196,14 @@ bool CalcTangentsProcess::ProcessMesh( aiMesh* pMesh, unsigned int meshIndex)
}
// tangent points in the direction where to positive X axis of the texture coord's would point in model space
// bitangent's points along the positive Y axis of the texture coord's, respectively
// bitangent's points along the negative Y axis of the texture coord's, respectively
aiVector3D tangent, bitangent;
tangent.x = (w.x * sy - v.x * ty) * dirCorrection;
tangent.y = (w.y * sy - v.y * ty) * dirCorrection;
tangent.z = (w.z * sy - v.z * ty) * dirCorrection;
bitangent.x = (w.x * sx - v.x * tx) * dirCorrection;
bitangent.y = (w.y * sx - v.y * tx) * dirCorrection;
bitangent.z = (w.z * sx - v.z * tx) * dirCorrection;
bitangent.x = (v.x * tx - w.x * sx) * dirCorrection;
bitangent.y = (v.y * tx - w.y * sx) * dirCorrection;
bitangent.z = (v.z * tx - w.z * sx) * dirCorrection;
// store for every vertex of that face
for( unsigned int b = 0; b < face.mNumIndices; ++b ) {

View File

@@ -29,3 +29,7 @@ In glTF2Importer.cpp, change from:
ai_anim->mNumChannels = r.skins[0].jointNames.size();
to:
ai_anim->mNumChannels = r.skins.Size() > 0 ? r.skins[0].jointNames.size() : 0;
(2)
Negate the bitangent in CalcTangentsProcess.cpp