From bf28c29f5098de91dac9d280961c1bcb12a07f05 Mon Sep 17 00:00:00 2001 From: Par Winzell Date: Tue, 17 Oct 2017 20:40:14 -0700 Subject: [PATCH] Multiple fixes for transparency. - alphaMode is only BLEND for transparent materials. - We use RawMaterial.type to figure out what's transparent. - FBX TransparencyFactor is not opacity, but 1.0-opacity. - Treat vertex coloured materials as transparent - We should at least iterate over vertices here and see if any of them actually are transparent - Sort triangles properly: transparent ones render last! --- src/Fbx2Raw.cpp | 2 +- src/Raw2Gltf.cpp | 7 ++++++- src/RawModel.cpp | 8 ++++---- src/glTF/MaterialData.cpp | 5 +++-- src/glTF/MaterialData.h | 3 ++- 5 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/Fbx2Raw.cpp b/src/Fbx2Raw.cpp index b17c2a4..c1bc134 100644 --- a/src/Fbx2Raw.cpp +++ b/src/Fbx2Raw.cpp @@ -169,7 +169,7 @@ public: fmt::printf("Warning: Mat [%s]: Can't handle texture for %s; discarding.\n", name, FbxSurfaceMaterial::sTransparencyFactor); } // FBX color is RGB, so we supply the A channel from TransparencyFactor - res.colDiffuse[3] = transparency[3]; + res.colDiffuse[3] = 1.0 - transparency[3]; return res; } diff --git a/src/Raw2Gltf.cpp b/src/Raw2Gltf.cpp index 1a1a878..2ea7465 100644 --- a/src/Raw2Gltf.cpp +++ b/src/Raw2Gltf.cpp @@ -367,6 +367,11 @@ ModelData *Raw2Gltf( for (int materialIndex = 0; materialIndex < raw.GetMaterialCount(); materialIndex++) { const RawMaterial &material = raw.GetMaterial(materialIndex); + const bool isTransparent = + material.type == RAW_MATERIAL_TYPE_VERTEX_COLORED || + material.type == RAW_MATERIAL_TYPE_SKINNED_VERTEX_COLORED || + material.type == RAW_MATERIAL_TYPE_TRANSPARENT || + material.type == RAW_MATERIAL_TYPE_SKINNED_TRANSPARENT; // find a texture by usage and return it as a TextureData*, or nullptr if none exists. auto getTex = [&](RawTextureUsage usage) @@ -407,7 +412,7 @@ ModelData *Raw2Gltf( } std::shared_ptr mData = gltf->materials.hold( new MaterialData( - material.name, getTex(RAW_TEXTURE_USAGE_NORMAL), + material.name, isTransparent, getTex(RAW_TEXTURE_USAGE_NORMAL), getTex(RAW_TEXTURE_USAGE_EMISSIVE), material.emissiveFactor, khrComMat, pbrMetRough, pbrSpecGloss)); materialsByName[materialHash(material)] = mData; diff --git a/src/RawModel.cpp b/src/RawModel.cpp index 71737fa..d7231f1 100644 --- a/src/RawModel.cpp +++ b/src/RawModel.cpp @@ -95,7 +95,7 @@ int RawModel::AddTexture(const char *name, const char *fileName, const RawTextur } } - const ImageProperties properties = GetImageProperties(name); + const ImageProperties properties = GetImageProperties(fileName); RawTexture texture; texture.name = name; @@ -421,13 +421,13 @@ void RawModel::CreateMaterialModels( // Sort the transparent triangles in the reverse direction. std::sort(transparentTriangles.begin(), transparentTriangles.end(), TriangleModelSortNeg::Compare); - for (const auto &transparentTriangle : transparentTriangles) { - sortedTriangles.push_back(transparentTriangle); - } // Add the triangles to the sorted list. for (const auto &opaqueTriangle : opaqueTriangles) { sortedTriangles.push_back(opaqueTriangle); } + for (const auto &transparentTriangle : transparentTriangles) { + sortedTriangles.push_back(transparentTriangle); + } } else { sortedTriangles = triangles; std::sort(sortedTriangles.begin(), sortedTriangles.end(), TriangleModelSortPos::Compare); diff --git a/src/glTF/MaterialData.cpp b/src/glTF/MaterialData.cpp index 2c7a2ca..60984cc 100644 --- a/src/glTF/MaterialData.cpp +++ b/src/glTF/MaterialData.cpp @@ -153,13 +153,14 @@ void to_json(json &j, const PBRMetallicRoughness &d) } MaterialData::MaterialData( - std::string name, const TextureData *normalTexture, + std::string name, bool isTransparent, const TextureData *normalTexture, const TextureData *emissiveTexture, const Vec3f & emissiveFactor, std::shared_ptr const khrCommonMats, std::shared_ptr const pbrMetallicRoughness, std::shared_ptr const pbrSpecularGlossiness) : Holdable(), name(std::move(name)), + isTransparent(isTransparent), normalTexture(Tex::ref(normalTexture)), emissiveTexture(Tex::ref(emissiveTexture)), emissiveFactor(std::move(emissiveFactor)), @@ -171,7 +172,7 @@ json MaterialData::serialize() const { json result = { { "name", name }, - { "alphaMode", "BLEND" } + { "alphaMode", isTransparent ? "BLEND" : "OPAQUE" } }; if (normalTexture != nullptr) { diff --git a/src/glTF/MaterialData.h b/src/glTF/MaterialData.h index 6f701e5..3c45ed1 100644 --- a/src/glTF/MaterialData.h +++ b/src/glTF/MaterialData.h @@ -82,7 +82,7 @@ struct PBRMetallicRoughness struct MaterialData : Holdable { MaterialData( - std::string name, const TextureData *normalTexture, + std::string name, bool isTransparent, const TextureData *normalTexture, const TextureData *emissiveTexture, const Vec3f &emissiveFactor, std::shared_ptr const khrCommonMats, std::shared_ptr const pbrMetallicRoughness, @@ -91,6 +91,7 @@ struct MaterialData : Holdable json serialize() const override; const std::string name; + const bool isTransparent; const std::unique_ptr normalTexture; const std::unique_ptr emissiveTexture; const Vec3f emissiveFactor;