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!
This commit is contained in:
Par Winzell 2017-10-17 20:40:14 -07:00 committed by Pär Winzell
parent d4ac174023
commit bf28c29f50
5 changed files with 16 additions and 9 deletions

View File

@ -169,7 +169,7 @@ public:
fmt::printf("Warning: Mat [%s]: Can't handle texture for %s; discarding.\n", name, FbxSurfaceMaterial::sTransparencyFactor); 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 // 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; return res;
} }

View File

@ -367,6 +367,11 @@ ModelData *Raw2Gltf(
for (int materialIndex = 0; materialIndex < raw.GetMaterialCount(); materialIndex++) { for (int materialIndex = 0; materialIndex < raw.GetMaterialCount(); materialIndex++) {
const RawMaterial &material = raw.GetMaterial(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. // find a texture by usage and return it as a TextureData*, or nullptr if none exists.
auto getTex = [&](RawTextureUsage usage) auto getTex = [&](RawTextureUsage usage)
@ -407,7 +412,7 @@ ModelData *Raw2Gltf(
} }
std::shared_ptr<MaterialData> mData = gltf->materials.hold( std::shared_ptr<MaterialData> mData = gltf->materials.hold(
new MaterialData( new MaterialData(
material.name, getTex(RAW_TEXTURE_USAGE_NORMAL), material.name, isTransparent, getTex(RAW_TEXTURE_USAGE_NORMAL),
getTex(RAW_TEXTURE_USAGE_EMISSIVE), material.emissiveFactor, getTex(RAW_TEXTURE_USAGE_EMISSIVE), material.emissiveFactor,
khrComMat, pbrMetRough, pbrSpecGloss)); khrComMat, pbrMetRough, pbrSpecGloss));
materialsByName[materialHash(material)] = mData; materialsByName[materialHash(material)] = mData;

View File

@ -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; RawTexture texture;
texture.name = name; texture.name = name;
@ -421,13 +421,13 @@ void RawModel::CreateMaterialModels(
// Sort the transparent triangles in the reverse direction. // Sort the transparent triangles in the reverse direction.
std::sort(transparentTriangles.begin(), transparentTriangles.end(), TriangleModelSortNeg::Compare); std::sort(transparentTriangles.begin(), transparentTriangles.end(), TriangleModelSortNeg::Compare);
for (const auto &transparentTriangle : transparentTriangles) {
sortedTriangles.push_back(transparentTriangle);
}
// Add the triangles to the sorted list. // Add the triangles to the sorted list.
for (const auto &opaqueTriangle : opaqueTriangles) { for (const auto &opaqueTriangle : opaqueTriangles) {
sortedTriangles.push_back(opaqueTriangle); sortedTriangles.push_back(opaqueTriangle);
} }
for (const auto &transparentTriangle : transparentTriangles) {
sortedTriangles.push_back(transparentTriangle);
}
} else { } else {
sortedTriangles = triangles; sortedTriangles = triangles;
std::sort(sortedTriangles.begin(), sortedTriangles.end(), TriangleModelSortPos::Compare); std::sort(sortedTriangles.begin(), sortedTriangles.end(), TriangleModelSortPos::Compare);

View File

@ -153,13 +153,14 @@ void to_json(json &j, const PBRMetallicRoughness &d)
} }
MaterialData::MaterialData( MaterialData::MaterialData(
std::string name, const TextureData *normalTexture, std::string name, bool isTransparent, const TextureData *normalTexture,
const TextureData *emissiveTexture, const Vec3f & emissiveFactor, const TextureData *emissiveTexture, const Vec3f & emissiveFactor,
std::shared_ptr<KHRCommonMats> const khrCommonMats, std::shared_ptr<KHRCommonMats> const khrCommonMats,
std::shared_ptr<PBRMetallicRoughness> const pbrMetallicRoughness, std::shared_ptr<PBRMetallicRoughness> const pbrMetallicRoughness,
std::shared_ptr<PBRSpecularGlossiness> const pbrSpecularGlossiness) std::shared_ptr<PBRSpecularGlossiness> const pbrSpecularGlossiness)
: Holdable(), : Holdable(),
name(std::move(name)), name(std::move(name)),
isTransparent(isTransparent),
normalTexture(Tex::ref(normalTexture)), normalTexture(Tex::ref(normalTexture)),
emissiveTexture(Tex::ref(emissiveTexture)), emissiveTexture(Tex::ref(emissiveTexture)),
emissiveFactor(std::move(emissiveFactor)), emissiveFactor(std::move(emissiveFactor)),
@ -171,7 +172,7 @@ json MaterialData::serialize() const
{ {
json result = { json result = {
{ "name", name }, { "name", name },
{ "alphaMode", "BLEND" } { "alphaMode", isTransparent ? "BLEND" : "OPAQUE" }
}; };
if (normalTexture != nullptr) { if (normalTexture != nullptr) {

View File

@ -82,7 +82,7 @@ struct PBRMetallicRoughness
struct MaterialData : Holdable struct MaterialData : Holdable
{ {
MaterialData( MaterialData(
std::string name, const TextureData *normalTexture, std::string name, bool isTransparent, const TextureData *normalTexture,
const TextureData *emissiveTexture, const Vec3f &emissiveFactor, const TextureData *emissiveTexture, const Vec3f &emissiveFactor,
std::shared_ptr<KHRCommonMats> const khrCommonMats, std::shared_ptr<KHRCommonMats> const khrCommonMats,
std::shared_ptr<PBRMetallicRoughness> const pbrMetallicRoughness, std::shared_ptr<PBRMetallicRoughness> const pbrMetallicRoughness,
@ -91,6 +91,7 @@ struct MaterialData : Holdable
json serialize() const override; json serialize() const override;
const std::string name; const std::string name;
const bool isTransparent;
const std::unique_ptr<const Tex> normalTexture; const std::unique_ptr<const Tex> normalTexture;
const std::unique_ptr<const Tex> emissiveTexture; const std::unique_ptr<const Tex> emissiveTexture;
const Vec3f emissiveFactor; const Vec3f emissiveFactor;