diff --git a/README.md b/README.md index 60e6c98..aa2ec16 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,10 @@ Usage: --pbr-specular-glossiness (WIP) Experimentally fill in the KHR_materials_pbrSpecularGlossiness extension. + --blend-shape-normals Include blend shape normals, if reported + present by the FBX SDK. + --blend-shape-tangents Include blend shape tangents, if reported + present by the FBX SDK. -k, --keep-attribute arg Used repeatedly to build a limiting set of vertex attributes to keep. -v, --verbose Enable verbose output. @@ -81,6 +85,13 @@ Some of these switches are not obvious: the conversion process. This is a way to trim the size of the resulting glTF if you know the FBX contains superfluous attributes. The supported arguments are `position`, `normal`, `tangent`, `color`, `uv0`, and `uv1`. +- When **blend shapes** are present, you may use `--blend-shape-normals` and + `--blend-shape-tangents` to include normal and tangent attributes in the glTF + morph targets. They are not included by default because they rarely or never + seem to be correctly present in the actual FBX source, which means the SDK + must be computing them from geometry, unasked? In any case, they are beyond + the control of the artist, and can yield strange crinkly behaviour. Since + they also take up significant space in the output file, we made them opt-in. ## Building it on your own diff --git a/src/Raw2Gltf.cpp b/src/Raw2Gltf.cpp index 2c06466..9ed143e 100644 --- a/src/Raw2Gltf.cpp +++ b/src/Raw2Gltf.cpp @@ -619,10 +619,10 @@ ModelData *Raw2Gltf( auto blendVertex = surfaceModel.GetVertex(jj).blends[channelIx]; shapeBounds.AddPoint(blendVertex.position); positions.push_back(blendVertex.position); - if (channel.hasNormals) { + if (options.useBlendShapeTangents && channel.hasNormals) { normals.push_back(blendVertex.normal); } - if (channel.hasTangents) { + if (options.useBlendShapeTangents && channel.hasTangents) { tangents.push_back(blendVertex.tangent); } } @@ -633,14 +633,14 @@ ModelData *Raw2Gltf( pAcc->max = toStdVec(shapeBounds.max); std::shared_ptr nAcc; - if (channel.hasNormals) { + if (!normals.empty()) { nAcc = gltf->AddAccessorWithView( *gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER), GLT_VEC3F, normals); } std::shared_ptr tAcc; - if (channel.hasTangents) { + if (!tangents.empty()) { nAcc = gltf->AddAccessorWithView( *gltf->GetAlignedBufferView(buffer, BufferViewData::GL_ARRAY_BUFFER), GLT_VEC4F, tangents); diff --git a/src/Raw2Gltf.h b/src/Raw2Gltf.h index 5de9218..8e6ecf5 100644 --- a/src/Raw2Gltf.h +++ b/src/Raw2Gltf.h @@ -53,6 +53,10 @@ struct GltfOptions bool usePBRMetRough; /** Whether to use KHR_materials_pbrSpecularGlossiness to extend material definitions. */ bool usePBRSpecGloss; + /** Whether to include blend shape normals, if present according to the SDK. */ + bool useBlendShapeNormals; + /** Whether to include blend shape tangents, if present according to the SDK. */ + bool useBlendShapeTangents; }; struct ComponentType { diff --git a/src/main.cpp b/src/main.cpp index 0fcd6bc..faa6c2d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -44,12 +44,14 @@ int main(int argc, char *argv[]) GltfOptions gltfOptions{ -1, // keepAttribs - false, // outputBinary - false, // embedResources - false, // useDraco - false, // useKHRMatCom - false, // usePBRMetRough - false // usePBRSpecGloss + false, // outputBinary + false, // embedResources + false, // useDraco + false, // useKHRMatCom + false, // usePBRMetRough + false, // usePBRSpecGloss + false, // useBlendShapeNormals + false, // useBlendShapeTangents }; options.positional_help("[]"); @@ -81,6 +83,12 @@ int main(int argc, char *argv[]) ( "pbr-specular-glossiness", "(WIP) Experimentally fill in the KHR_materials_pbrSpecularGlossiness extension.", cxxopts::value(gltfOptions.usePBRSpecGloss)) + ( + "blend-shape-normals", "Include blend shape normals, if reported present by the FBX SDK.", + cxxopts::value(gltfOptions.useBlendShapeNormals)) + ( + "blend-shape-tangents", "Include blend shape tangents, if reported present by the FBX SDK.", + cxxopts::value(gltfOptions.useBlendShapeTangents)) ( "k,keep-attribute", "Used repeatedly to build a limiting set of vertex attributes to keep.", cxxopts::value>())