First functional checkpoint.

We've now got everything moving correctly from FBX to glTF.

Much cleanup remains.
This commit is contained in:
Par Winzell 2017-11-24 21:55:03 -08:00
parent 651f133ae1
commit d67722a5d7
5 changed files with 231 additions and 191 deletions

View File

@ -88,51 +88,47 @@ private:
const FbxLayerElementArrayTemplate<int> *indices; const FbxLayerElementArrayTemplate<int> *indices;
}; };
class FbxRoughMetMaterialAccess struct FbxMaterialInfo {
{ FbxMaterialInfo(const FbxString &name, const FbxString &shadingModel)
struct FbxMaterialProperties { : name(name),
const FbxFileTexture *texColor {}; shadingModel(shadingModel)
FbxVector4 colBase { 1, 1, 1, 1 }; {}
const FbxFileTexture *texNormal {};
const FbxFileTexture *texMetallic {};
FbxDouble metallic {};
const FbxFileTexture *texRoughness {};
FbxDouble roughness {};
const FbxFileTexture *texEmissive {};
FbxVector4 colEmissive {};
FbxDouble emissiveIntensity;
const FbxFileTexture *texAmbientOcclusion {};
};
private:
const FbxSurfaceMaterial *fbxMaterial;
const std::map<const FbxTexture *, FbxString> &textureLocations;
public:
const FbxString name; const FbxString name;
const FbxString shadingModel; const FbxString shadingModel;
};
const struct FbxMaterialProperties props; struct FbxRoughMetMaterialInfo : FbxMaterialInfo {
static constexpr const char *FBX_SHADER_METROUGH = "MetallicRoughness";
explicit FbxRoughMetMaterialAccess( FbxRoughMetMaterialInfo(const FbxString &name, const FbxString &shadingModel)
const FbxSurfaceMaterial *fbxMaterial, const std::map<const FbxTexture *, FbxString> &textureNames) : : FbxMaterialInfo(name, shadingModel)
fbxMaterial(fbxMaterial),
name(fbxMaterial->GetName()),
shadingModel(fbxMaterial->ShadingModel),
textureLocations(textureNames),
props(extractTextures())
{} {}
const FbxFileTexture *texColor {};
FbxVector4 colBase { 1, 1, 1, 1 };
const FbxFileTexture *texNormal {};
const FbxFileTexture *texMetallic {};
FbxDouble metallic {};
const FbxFileTexture *texRoughness {};
FbxDouble roughness {};
const FbxFileTexture *texEmissive {};
FbxVector4 colEmissive {};
FbxDouble emissiveIntensity {};
const FbxFileTexture *texAmbientOcclusion {};
struct FbxMaterialProperties extractTextures() { static std::unique_ptr<FbxRoughMetMaterialInfo> From(
struct FbxMaterialProperties res { }; FbxSurfaceMaterial *fbxMaterial,
const std::map<const FbxTexture *, FbxString> &textureLocations)
{
std::unique_ptr<FbxRoughMetMaterialInfo> res(new FbxRoughMetMaterialInfo(fbxMaterial->GetName(), FBX_SHADER_METROUGH));
const FbxProperty mayaProp = fbxMaterial->FindProperty("Maya"); const FbxProperty mayaProp = fbxMaterial->FindProperty("Maya");
if (mayaProp.GetPropertyDataType() != FbxCompoundDT) { if (mayaProp.GetPropertyDataType() != FbxCompoundDT) {
return res; return nullptr;
}
if (!fbxMaterial->ShadingModel.Get().IsEmpty()) {
fmt::printf("Warning: Material %s has surprising shading model: %s\n",
fbxMaterial->GetName(), fbxMaterial->ShadingModel.Get());
} }
auto foo = mayaProp.GetPropertyDataType();
fmt::printf("Maya property type for material %s: %s\n", fbxMaterial->GetName(), foo.GetName());
auto getTex = [&](std::string propName) { auto getTex = [&](std::string propName) {
const FbxFileTexture *ptr = nullptr; const FbxFileTexture *ptr = nullptr;
@ -143,62 +139,128 @@ public:
if (texProp.IsValid()) { if (texProp.IsValid()) {
fmt::printf("%s property type for material %s: %s\n", propName, fbxMaterial->GetName(), texProp.GetPropertyDataType().GetName()); fmt::printf("%s property type for material %s: %s\n", propName, fbxMaterial->GetName(), texProp.GetPropertyDataType().GetName());
ptr = texProp.GetSrcObject<FbxFileTexture>(); ptr = texProp.GetSrcObject<FbxFileTexture>();
if (ptr != nullptr && textureLocations.find(ptr) == textureLocations.end()) {
ptr = nullptr;
}
} }
} }
return ptr; return ptr;
}; };
res.texNormal = getTex("normal"); auto getVec = [&](std::string propName) -> FbxDouble3 {
res.texColor = getTex("color"); const FbxProperty vecProp = mayaProp.FindHierarchical(propName.c_str());
res.texAmbientOcclusion = getTex("ao"); return vecProp.IsValid() ? vecProp.Get<FbxDouble3>() : FbxDouble3(1, 1, 1);
res.texEmissive = getTex("emissive"); };
res.texMetallic = getTex("metallic");
res.texRoughness = getTex("roughness"); auto getVal = [&](std::string propName) -> FbxDouble {
const FbxProperty vecProp = mayaProp.FindHierarchical(propName .c_str());
return vecProp.IsValid() ? vecProp.Get<FbxDouble>() : 0;
};
res->texNormal = getTex("normal");
res->texColor = getTex("color");
res->colBase = getVec("base_color");
res->texAmbientOcclusion = getTex("ao");
res->texEmissive = getTex("emissive");
res->colEmissive = getVec("emissive");
res->emissiveIntensity = getVal("emissive_intensity");
res->texMetallic = getTex("metallic");
res->metallic = getVal("metallic");
res->texRoughness = getTex("roughness");
res->roughness = getVal("roughness");
return res; return res;
} }
}; };
class FbxMaterialAccess struct FbxTraditionalMaterialInfo : FbxMaterialInfo {
{ static constexpr const char *FBX_SHADER_LAMBERT = "Lambert";
struct FbxMaterialProperties { static constexpr const char *FBX_SHADER_BLINN = "Blinn";
FbxFileTexture *texAmbient {}; static constexpr const char *FBX_SHADER_PHONG = "Phong";
FbxVector4 colAmbient {};
FbxFileTexture *texSpecular {};
FbxVector4 colSpecular {};
FbxFileTexture *texDiffuse {};
FbxVector4 colDiffuse {};
FbxFileTexture *texEmissive {};
FbxVector4 colEmissive {};
FbxFileTexture *texNormal {};
FbxFileTexture *texShininess {};
FbxDouble shininess {};
};
private: FbxTraditionalMaterialInfo(const FbxString &name, const FbxString &shadingModel)
const FbxSurfaceMaterial *fbxMaterial; : FbxMaterialInfo(name, shadingModel)
const std::map<const FbxTexture *, FbxString> &textureLocations;
public:
const FbxString name;
const FbxString shadingModel;
const struct FbxMaterialProperties props;
explicit FbxMaterialAccess(
const FbxSurfaceMaterial *fbxMaterial, const std::map<const FbxTexture *, FbxString> &textureNames) :
fbxMaterial(fbxMaterial),
name(fbxMaterial->GetName()),
shadingModel(fbxMaterial->ShadingModel),
textureLocations(textureNames),
props(extractTextures())
{} {}
struct FbxMaterialProperties extractTextures() { FbxFileTexture *texAmbient {};
struct FbxMaterialProperties res; FbxVector4 colAmbient {};
FbxFileTexture *texSpecular {};
FbxVector4 colSpecular {};
FbxFileTexture *texDiffuse {};
FbxVector4 colDiffuse {};
FbxFileTexture *texEmissive {};
FbxVector4 colEmissive {};
FbxFileTexture *texNormal {};
FbxFileTexture *texShininess {};
FbxDouble shininess {};
static std::unique_ptr<FbxTraditionalMaterialInfo> From(
FbxSurfaceMaterial *fbxMaterial,
const std::map<const FbxTexture *, FbxString> &textureLocations)
{
auto getSurfaceScalar = [&](const char *propName) -> std::tuple<FbxDouble, FbxFileTexture *> {
const FbxProperty prop = fbxMaterial->FindProperty(propName);
FbxDouble val(0);
FbxFileTexture *tex = prop.GetSrcObject<FbxFileTexture>();
if (tex != nullptr && textureLocations.find(tex) == textureLocations.end()) {
tex = nullptr;
}
if (tex == nullptr && prop.IsValid()) {
val = prop.Get<FbxDouble>();
}
return std::make_tuple(val, tex);
};
auto getSurfaceVector = [&](const char *propName) -> std::tuple<FbxDouble3, FbxFileTexture *> {
const FbxProperty prop = fbxMaterial->FindProperty(propName);
FbxDouble3 val(1, 1, 1);
FbxFileTexture *tex = prop.GetSrcObject<FbxFileTexture>();
if (tex != nullptr && textureLocations.find(tex) == textureLocations.end()) {
tex = nullptr;
}
if (tex == nullptr && prop.IsValid()) {
val = prop.Get<FbxDouble3>();
}
return std::make_tuple(val, tex);
};
auto getSurfaceValues = [&](const char *colName, const char *facName) -> std::tuple<FbxVector4, FbxFileTexture *, FbxFileTexture *> {
const FbxProperty colProp = fbxMaterial->FindProperty(colName);
const FbxProperty facProp = fbxMaterial->FindProperty(facName);
FbxDouble3 colorVal(1, 1, 1);
FbxDouble factorVal(1);
FbxFileTexture *colTex = colProp.GetSrcObject<FbxFileTexture>();
if (colTex != nullptr && textureLocations.find(colTex) == textureLocations.end()) {
colTex = nullptr;
}
if (colTex == nullptr && colProp.IsValid()) {
colorVal = colProp.Get<FbxDouble3>();
}
FbxFileTexture *facTex = facProp.GetSrcObject<FbxFileTexture>();
if (facTex != nullptr && textureLocations.find(facTex) == textureLocations.end()) {
facTex = nullptr;
}
if (facTex == nullptr && facProp.IsValid()) {
factorVal = facProp.Get<FbxDouble>();
}
auto val = FbxVector4(
colorVal[0] * factorVal,
colorVal[1] * factorVal,
colorVal[2] * factorVal,
factorVal);
return std::make_tuple(val, colTex, facTex);
};
std::string name = fbxMaterial->GetName();
std::unique_ptr<FbxTraditionalMaterialInfo> res(new FbxTraditionalMaterialInfo(name.c_str(), fbxMaterial->sShadingModel));
// four properties are on the same structure and follow the same rules // four properties are on the same structure and follow the same rules
auto handleBasicProperty = [&](const char *colName, const char *facName) { auto handleBasicProperty = [&](const char *colName, const char *facName) -> std::tuple<FbxVector4, FbxFileTexture *>{
FbxFileTexture *colTex, *facTex; FbxFileTexture *colTex, *facTex;
FbxVector4 vec; FbxVector4 vec;
@ -212,20 +274,20 @@ public:
return std::make_tuple(vec, facTex); return std::make_tuple(vec, facTex);
}; };
std::tie(res.colAmbient, res.texAmbient) = std::tie(res->colAmbient, res->texAmbient) =
handleBasicProperty(FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor); handleBasicProperty(FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor);
std::tie(res.colSpecular, res.texSpecular) = std::tie(res->colSpecular, res->texSpecular) =
handleBasicProperty(FbxSurfaceMaterial::sSpecular, FbxSurfaceMaterial::sSpecularFactor); handleBasicProperty(FbxSurfaceMaterial::sSpecular, FbxSurfaceMaterial::sSpecularFactor);
std::tie(res.colDiffuse, res.texDiffuse) = std::tie(res->colDiffuse, res->texDiffuse) =
handleBasicProperty(FbxSurfaceMaterial::sDiffuse, FbxSurfaceMaterial::sDiffuseFactor); handleBasicProperty(FbxSurfaceMaterial::sDiffuse, FbxSurfaceMaterial::sDiffuseFactor);
std::tie(res.colEmissive, res.texEmissive) = std::tie(res->colEmissive, res->texEmissive) =
handleBasicProperty(FbxSurfaceMaterial::sEmissive, FbxSurfaceMaterial::sEmissiveFactor); handleBasicProperty(FbxSurfaceMaterial::sEmissive, FbxSurfaceMaterial::sEmissiveFactor);
// the normal map can only ever be a map, ignore everything else // the normal map can only ever be a map, ignore everything else
std::tie(std::ignore, res.texNormal) = getSurfaceVector(FbxSurfaceMaterial::sNormalMap); std::tie(std::ignore, res->texNormal) = getSurfaceVector(FbxSurfaceMaterial::sNormalMap);
// shininess can be a map or a factor // shininess can be a map or a factor
std::tie(res.shininess, res.texShininess) = getSurfaceScalar(FbxSurfaceMaterial::sShininess); std::tie(res->shininess, res->texShininess) = getSurfaceScalar(FbxSurfaceMaterial::sShininess);
// for transparency we just want a constant vector value; // for transparency we just want a constant vector value;
FbxVector4 transparency; FbxVector4 transparency;
@ -240,74 +302,24 @@ 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 calculate the A channel as the average of the FBX transparency color vector // FBX color is RGB, so we calculate the A channel as the average of the FBX transparency color vector
res.colDiffuse[3] = 1.0 - (transparency[0] + transparency[1] + transparency[2])/3.0; res->colDiffuse[3] = 1.0 - (transparency[0] + transparency[1] + transparency[2])/3.0;
return res; return res;
} }
std::tuple<FbxDouble, FbxFileTexture *> getSurfaceScalar(const char *propName) const
{
const FbxProperty prop = fbxMaterial->FindProperty(propName);
FbxDouble val(0);
FbxFileTexture *tex = prop.GetSrcObject<FbxFileTexture>();
if (tex != nullptr && textureLocations.find(tex) == textureLocations.end()) {
tex = nullptr;
}
if (tex == nullptr && prop.IsValid()) {
val = prop.Get<FbxDouble>();
}
return std::make_tuple(val, tex);
}
std::tuple<FbxDouble3, FbxFileTexture *> getSurfaceVector(const char *propName) const
{
const FbxProperty prop = fbxMaterial->FindProperty(propName);
FbxDouble3 val(1, 1, 1);
FbxFileTexture *tex = prop.GetSrcObject<FbxFileTexture>();
if (tex != nullptr && textureLocations.find(tex) == textureLocations.end()) {
tex = nullptr;
}
if (tex == nullptr && prop.IsValid()) {
val = prop.Get<FbxDouble3>();
}
return std::make_tuple(val, tex);
}
std::tuple<FbxVector4, FbxFileTexture *, FbxFileTexture *> getSurfaceValues(const char *colName, const char *facName) const
{
const FbxProperty colProp = fbxMaterial->FindProperty(colName);
const FbxProperty facProp = fbxMaterial->FindProperty(facName);
FbxDouble3 colorVal(1, 1, 1);
FbxDouble factorVal(1);
FbxFileTexture *colTex = colProp.GetSrcObject<FbxFileTexture>();
if (colTex != nullptr && textureLocations.find(colTex) == textureLocations.end()) {
colTex = nullptr;
}
if (colTex == nullptr && colProp.IsValid()) {
colorVal = colProp.Get<FbxDouble3>();
}
FbxFileTexture *facTex = facProp.GetSrcObject<FbxFileTexture>();
if (facTex != nullptr && textureLocations.find(facTex) == textureLocations.end()) {
facTex = nullptr;
}
if (facTex == nullptr && facProp.IsValid()) {
factorVal = facProp.Get<FbxDouble>();
}
auto val = FbxVector4(
colorVal[0] * factorVal,
colorVal[1] * factorVal,
colorVal[2] * factorVal,
factorVal);
return std::make_tuple(val, colTex, facTex);
};
}; };
std::unique_ptr<FbxMaterialInfo>
GetMaterialInfo(FbxSurfaceMaterial *material, const std::map<const FbxTexture *, FbxString> &textureLocations)
{
std::unique_ptr<FbxMaterialInfo> res;
res = FbxRoughMetMaterialInfo::From(material, textureLocations);
if (!res) {
res = FbxTraditionalMaterialInfo::From(material, textureLocations);
}
return res;
}
class FbxMaterialsAccess class FbxMaterialsAccess
{ {
public: public:
@ -345,14 +357,14 @@ public:
} }
auto summary = summaries[materialNum]; auto summary = summaries[materialNum];
if (summary == nullptr) { if (summary == nullptr) {
summary = summaries[materialNum] = std::make_shared<FbxRoughMetMaterialAccess>( summary = summaries[materialNum] = GetMaterialInfo(
mesh->GetNode()->GetSrcObject<FbxSurfaceMaterial>(materialNum), mesh->GetNode()->GetSrcObject<FbxSurfaceMaterial>(materialNum),
textureLocations); textureLocations);
} }
} }
} }
const std::shared_ptr<FbxRoughMetMaterialAccess> GetMaterial(const int polygonIndex) const const std::shared_ptr<FbxMaterialInfo> GetMaterial(const int polygonIndex) const
{ {
if (mappingMode != FbxGeometryElement::eNone) { if (mappingMode != FbxGeometryElement::eNone) {
const int materialNum = indices->GetAt((mappingMode == FbxGeometryElement::eByPolygon) ? polygonIndex : 0); const int materialNum = indices->GetAt((mappingMode == FbxGeometryElement::eByPolygon) ? polygonIndex : 0);
@ -365,10 +377,10 @@ public:
} }
private: private:
FbxGeometryElement::EMappingMode mappingMode; FbxGeometryElement::EMappingMode mappingMode;
std::vector<std::shared_ptr<FbxRoughMetMaterialAccess>> summaries {}; std::vector<std::shared_ptr<FbxMaterialInfo>> summaries {};
const FbxMesh *mesh; const FbxMesh *mesh;
const FbxLayerElementArrayTemplate<int> *indices; const FbxLayerElementArrayTemplate<int> *indices;
}; };
class FbxSkinningAccess class FbxSkinningAccess
@ -757,15 +769,14 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
for (int polygonIndex = 0; polygonIndex < pMesh->GetPolygonCount(); polygonIndex++) { for (int polygonIndex = 0; polygonIndex < pMesh->GetPolygonCount(); polygonIndex++) {
FBX_ASSERT(pMesh->GetPolygonSize(polygonIndex) == 3); FBX_ASSERT(pMesh->GetPolygonSize(polygonIndex) == 3);
const std::shared_ptr<FbxRoughMetMaterialAccess> fbxMaterial = materials.GetMaterial(polygonIndex); int textures[RAW_TEXTURE_USAGE_MAX] { -1 };
int textures[RAW_TEXTURE_USAGE_MAX];
std::fill_n(textures, RAW_TEXTURE_USAGE_MAX, -1); std::fill_n(textures, RAW_TEXTURE_USAGE_MAX, -1);
FbxString shadingModel, materialName; FbxString shadingModel, materialName;
FbxVector4 ambient, specular, diffuse, emissive; FbxVector4 ambient, specular, diffuse, emissive;
FbxDouble shininess; FbxDouble shininess, emissiveIntensity, metallic, roughness;
const std::shared_ptr<FbxMaterialInfo> fbxMaterial = materials.GetMaterial(polygonIndex);
if (fbxMaterial == nullptr) { if (fbxMaterial == nullptr) {
materialName = "DefaultMaterial"; materialName = "DefaultMaterial";
shadingModel = "Lambert"; shadingModel = "Lambert";
@ -774,8 +785,6 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
materialName = fbxMaterial->name; materialName = fbxMaterial->name;
shadingModel = fbxMaterial->shadingModel; shadingModel = fbxMaterial->shadingModel;
const auto &matProps = fbxMaterial->props;
const auto maybeAddTexture = [&](const FbxFileTexture *tex, RawTextureUsage usage) { const auto maybeAddTexture = [&](const FbxFileTexture *tex, RawTextureUsage usage) {
if (tex != nullptr) { if (tex != nullptr) {
// dig out the inferred filename from the textureLocations map // dig out the inferred filename from the textureLocations map
@ -784,12 +793,37 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
} }
}; };
maybeAddTexture(matProps.texColor, RAW_TEXTURE_USAGE_ALBEDO); if (shadingModel == FbxRoughMetMaterialInfo::FBX_SHADER_METROUGH) {
maybeAddTexture(matProps.texNormal, RAW_TEXTURE_USAGE_NORMAL); FbxRoughMetMaterialInfo *matProps = static_cast<FbxRoughMetMaterialInfo *>(fbxMaterial.get());
maybeAddTexture(matProps.texEmissive, RAW_TEXTURE_USAGE_EMISSIVE);
maybeAddTexture(matProps.texRoughness, RAW_TEXTURE_USAGE_ROUGHNESS); maybeAddTexture(matProps->texColor, RAW_TEXTURE_USAGE_ALBEDO);
maybeAddTexture(matProps.texMetallic, RAW_TEXTURE_USAGE_METALLIC); diffuse = matProps->colBase;
maybeAddTexture(matProps.texAmbientOcclusion, RAW_TEXTURE_USAGE_OCCLUSION); maybeAddTexture(matProps->texNormal, RAW_TEXTURE_USAGE_NORMAL);
maybeAddTexture(matProps->texEmissive, RAW_TEXTURE_USAGE_EMISSIVE);
emissive = matProps->colEmissive;
emissiveIntensity = matProps->emissiveIntensity;
maybeAddTexture(matProps->texRoughness, RAW_TEXTURE_USAGE_ROUGHNESS);
maybeAddTexture(matProps->texMetallic, RAW_TEXTURE_USAGE_METALLIC);
metallic = matProps->metallic;
maybeAddTexture(matProps->texAmbientOcclusion, RAW_TEXTURE_USAGE_OCCLUSION);
roughness = matProps->roughness;
} else {
FbxTraditionalMaterialInfo *matProps = static_cast<FbxTraditionalMaterialInfo *>(fbxMaterial.get());
maybeAddTexture(matProps->texDiffuse, RAW_TEXTURE_USAGE_DIFFUSE);
diffuse = matProps->colDiffuse;
maybeAddTexture(matProps->texNormal, RAW_TEXTURE_USAGE_NORMAL);
maybeAddTexture(matProps->texEmissive, RAW_TEXTURE_USAGE_EMISSIVE);
emissive = matProps->colEmissive;
maybeAddTexture(matProps->texShininess, RAW_TEXTURE_USAGE_SHININESS);
shininess = matProps->shininess;
maybeAddTexture(matProps->texAmbient, RAW_TEXTURE_USAGE_AMBIENT);
ambient = matProps->colAmbient;
maybeAddTexture(matProps->texSpecular, RAW_TEXTURE_USAGE_SPECULAR);
specular = matProps->colSpecular;
}
} }
RawVertex rawVertices[3]; RawVertex rawVertices[3];
@ -919,7 +953,8 @@ static void ReadMesh(RawModel &raw, FbxScene *pScene, FbxNode *pNode, const std:
const RawMaterialType materialType = GetMaterialType(raw, textures, vertexTransparency, skinning.IsSkinned()); const RawMaterialType materialType = GetMaterialType(raw, textures, vertexTransparency, skinning.IsSkinned());
const int rawMaterialIndex = raw.AddMaterial( const int rawMaterialIndex = raw.AddMaterial(
materialName, shadingModel, materialType, textures, materialName, shadingModel, materialType, textures,
toVec3f(ambient), toVec4f(diffuse), toVec3f(specular), toVec3f(emissive), shininess); toVec3f(ambient), toVec4f(diffuse), toVec3f(specular), toVec3f(emissive),
emissiveIntensity, shininess, metallic, roughness);
raw.AddTriangle(rawVertexIndices[0], rawVertexIndices[1], rawVertexIndices[2], rawMaterialIndex, rawSurfaceIndex); raw.AddTriangle(rawVertexIndices[0], rawVertexIndices[1], rawVertexIndices[2], rawMaterialIndex, rawSurfaceIndex);
} }

View File

@ -565,11 +565,7 @@ ModelData *Raw2Gltf(
// albedo is basic // albedo is basic
const TextureData *albedoTex = simpleTex(RAW_TEXTURE_USAGE_ALBEDO); const TextureData *albedoTex = simpleTex(RAW_TEXTURE_USAGE_ALBEDO);
// if there's a met/rough texture, just set the factors to 1.0 multipliers, else use reasonable pbrMetRough.reset(new PBRMetallicRoughness(albedoTex, metRoughTex, material.diffuseFactor, material.metallic, material.roughness));
// defaults for a possible vertex-coloured or solid colour setup
float metallic = metRoughTex ? 1.0f : 0.3f;
float roughness = metRoughTex ? 1.0f : 0.6f;
pbrMetRough.reset(new PBRMetallicRoughness(albedoTex, metRoughTex, material.diffuseFactor, metallic, roughness));
} }
std::shared_ptr<PBRSpecularGlossiness> pbrSpecGloss; std::shared_ptr<PBRSpecularGlossiness> pbrSpecGloss;
@ -601,7 +597,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, isTransparent, simpleTex(RAW_TEXTURE_USAGE_NORMAL), material.name, isTransparent, simpleTex(RAW_TEXTURE_USAGE_NORMAL),
simpleTex(RAW_TEXTURE_USAGE_EMISSIVE), material.emissiveFactor, simpleTex(RAW_TEXTURE_USAGE_EMISSIVE), material.emissiveFactor * material.emissiveIntensity, // TODO: 1.0 default value for emissiveIntensity?
khrComMat, pbrMetRough, pbrSpecGloss)); khrComMat, pbrMetRough, pbrSpecGloss));
materialsByName[materialHash(material)] = mData; materialsByName[materialHash(material)] = mData;
} }

View File

@ -113,14 +113,14 @@ int RawModel::AddMaterial(const RawMaterial &material)
{ {
return AddMaterial( return AddMaterial(
material.name.c_str(), material.shadingModel.c_str(), material.type, material.textures, material.ambientFactor, material.name.c_str(), material.shadingModel.c_str(), material.type, material.textures, material.ambientFactor,
material.diffuseFactor, material.specularFactor, material.emissiveFactor, material.shininess); material.diffuseFactor, material.specularFactor, material.emissiveFactor, material.emissiveIntensity,
material.shininess, material.metallic, material.roughness);
} }
int RawModel::AddMaterial( int RawModel::AddMaterial(
const char *name, const char *shadingModel, const RawMaterialType materialType, const char *name, const char *shadingModel, const RawMaterialType materialType, const int textures[RAW_TEXTURE_USAGE_MAX],
const int textures[RAW_TEXTURE_USAGE_MAX], const Vec3f ambientFactor, const Vec3f ambientFactor, const Vec4f diffuseFactor, const Vec3f specularFactor, const Vec3f emissiveFactor,
const Vec4f diffuseFactor, const Vec3f specularFactor, float emissiveIntensity, float shinineness, float metallic, float roughness)
const Vec3f emissiveFactor, float shinineness)
{ {
for (size_t i = 0; i < materials.size(); i++) { for (size_t i = 0; i < materials.size(); i++) {
if (materials[i].name != name) { if (materials[i].name != name) {
@ -136,7 +136,10 @@ int RawModel::AddMaterial(
materials[i].diffuseFactor != diffuseFactor || materials[i].diffuseFactor != diffuseFactor ||
materials[i].specularFactor != specularFactor || materials[i].specularFactor != specularFactor ||
materials[i].emissiveFactor != emissiveFactor || materials[i].emissiveFactor != emissiveFactor ||
materials[i].shininess != shinineness) { materials[i].emissiveIntensity != emissiveIntensity ||
materials[i].shininess != shinineness ||
materials[i].metallic != metallic ||
materials[i].roughness != roughness) {
continue; continue;
} }
@ -150,14 +153,17 @@ int RawModel::AddMaterial(
} }
RawMaterial material; RawMaterial material;
material.name = name; material.name = name;
material.shadingModel = shadingModel; material.shadingModel = shadingModel;
material.type = materialType; material.type = materialType;
material.ambientFactor = ambientFactor; material.ambientFactor = ambientFactor;
material.diffuseFactor = diffuseFactor; material.diffuseFactor = diffuseFactor;
material.specularFactor = specularFactor; material.specularFactor = specularFactor;
material.emissiveFactor = emissiveFactor; material.emissiveFactor = emissiveFactor;
material.shininess = shinineness; material.emissiveIntensity = emissiveIntensity;
material.shininess = shinineness;
material.metallic = metallic;
material.roughness = roughness;
for (int i = 0; i < RAW_TEXTURE_USAGE_MAX; i++) { for (int i = 0; i < RAW_TEXTURE_USAGE_MAX; i++) {
material.textures[i] = textures[i]; material.textures[i] = textures[i];

View File

@ -179,7 +179,10 @@ struct RawMaterial
Vec4f diffuseFactor; Vec4f diffuseFactor;
Vec3f specularFactor; Vec3f specularFactor;
Vec3f emissiveFactor; Vec3f emissiveFactor;
float emissiveIntensity;
float shininess; float shininess;
float metallic;
float roughness;
int textures[RAW_TEXTURE_USAGE_MAX]; int textures[RAW_TEXTURE_USAGE_MAX];
}; };
@ -272,10 +275,9 @@ public:
int AddTexture(const std::string &name, const std::string &fileName, const std::string &fileLocation, RawTextureUsage usage); int AddTexture(const std::string &name, const std::string &fileName, const std::string &fileLocation, RawTextureUsage usage);
int AddMaterial(const RawMaterial &material); int AddMaterial(const RawMaterial &material);
int AddMaterial( int AddMaterial(
const char *name, const char *shadingModel, RawMaterialType materialType, const char *name, const char *shadingModel, const RawMaterialType materialType, const int textures[RAW_TEXTURE_USAGE_MAX],
const int textures[RAW_TEXTURE_USAGE_MAX], Vec3f ambientFactor, const Vec3f ambientFactor, const Vec4f diffuseFactor, const Vec3f specularFactor, const Vec3f emissiveFactor,
Vec4f diffuseFactor, Vec3f specularFactor, float emissiveIntensity, float shinineness, float metallic, float roughness);
Vec3f emissiveFactor, float shinineness);
int AddSurface(const RawSurface &suface); int AddSurface(const RawSurface &suface);
int AddSurface(const char *name, const char *nodeName); int AddSurface(const char *name, const char *nodeName);
int AddAnimation(const RawAnimation &animation); int AddAnimation(const RawAnimation &animation);

View File

@ -147,11 +147,12 @@ void to_json(json &j, const PBRMetallicRoughness &d)
} }
if (d.metRoughTexture != nullptr) { if (d.metRoughTexture != nullptr) {
j["metallicRoughnessTexture"] = *d.metRoughTexture; j["metallicRoughnessTexture"] = *d.metRoughTexture;
} // if a texture is provided, throw away metallic/roughness values
if (d.metallic != 1.0f) { j["roughnessFactor"] = 1.0f;
j["metallicFactor"] = 1.0f;
} else {
// without a texture, however, use metallic/roughness as constants
j["metallicFactor"] = d.metallic; j["metallicFactor"] = d.metallic;
}
if (d.roughness != 1.0f) {
j["roughnessFactor"] = d.roughness; j["roughnessFactor"] = d.roughness;
} }
} }