Renaming and rearranging the material fields to support PBR fbx materials

This commit is contained in:
samcake 2016-02-16 17:20:23 -08:00
parent 71863a1550
commit b03f639e2c
11 changed files with 99 additions and 26 deletions

View file

@ -865,6 +865,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
}
} else if (object.name == "Material") {
FBXMaterial material;
if (object.properties.at(1).toByteArray().contains("StingrayPBS1")) {
material.isPBSMaterial = true;
}
foreach (const FBXNode& subobject, object.children) {
bool properties = false;
QByteArray propertyName;
@ -879,7 +882,7 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
propertyName = "P";
index = 4;
}
if (properties) {
if (properties && !material.isPBSMaterial) {
foreach (const FBXNode& property, subobject.children) {
if (property.name == propertyName) {
if (property.properties.at(0) == "DiffuseColor") {
@ -914,6 +917,22 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
#endif
}
}
} else if (properties && material.isPBSMaterial) {
std::vector<std::string> unknowns;
foreach(const FBXNode& property, subobject.children) {
if (property.name == propertyName) {
if (property.properties.at(0) == "Maya|base_color") {
material.diffuseColor = getVec3(property.properties, index);
} else if (property.properties.at(0) == "Maya|metallic") {
material.metallic = property.properties.at(index).value<double>();
} else if (property.properties.at(0) == "Maya|roughness") {
material.roughness = property.properties.at(index).value<double>();
} else {
const QString propname = property.properties.at(0).toString();
unknowns.push_back(propname.toStdString());
}
}
}
}
#if defined(DEBUG_FBXREADER)
else {
@ -1032,7 +1051,9 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
QByteArray type = connection.properties.at(3).toByteArray().toLower();
if (type.contains("diffuse")) {
diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
} else if (type.contains("tex_color_map")) {
qDebug() << "insert color map for diffuse!";
diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
} else if (type.contains("transparentcolor")) { // it should be TransparentColor...
// THis is how Maya assign a texture that affect diffuse color AND transparency ?
diffuseTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
@ -1042,7 +1063,8 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
normalTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
} else if (type.contains("specular") || type.contains("reflection")) {
specularTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
} else if (type.contains("metallic")) {
metallicTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
} else if (type == "lcl rotation") {
localRotations.insert(getID(connection.properties, 2), getID(connection.properties, 1));
} else if (type == "lcl translation") {
@ -1056,8 +1078,11 @@ FBXGeometry* FBXReader::extractFBXGeometry(const QVariantHash& mapping, const QS
zComponents.insert(getID(connection.properties, 2), getID(connection.properties, 1));
} else if (type.contains("shininess")) {
shininessTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
counter++;
} else if (type.contains("roughness")) {
roughnessTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));
counter++;
} else if (_loadLightmaps && type.contains("emissive")) {
emissiveTextures.insert(getID(connection.properties, 2), getID(connection.properties, 1));

View file

@ -111,7 +111,8 @@ public:
QString texcoordSetName;
bool isBumpmap{ false };
bool isGlossmap{ true };
bool isNull() const { return name.isEmpty() && filename.isEmpty() && content.isEmpty(); }
};
@ -148,6 +149,9 @@ public:
float shininess = 23.0f;
float opacity = 1.0f;
float metallic{ 0.0f };
float roughness{ 1.0f };
QString materialID;
model::MaterialPointer _material;
@ -156,7 +160,10 @@ public:
FBXTexture normalTexture;
FBXTexture specularTexture;
FBXTexture emissiveTexture;
FBXTexture metallicTexture;
FBXTexture roughnessTexture;
bool isPBSMaterial{ false };
bool needTangentSpace() const;
};
@ -402,6 +409,9 @@ public:
QHash<QString, QString> specularTextures;
QHash<QString, QString> emissiveTextures;
QHash<QString, QString> ambientTextures;
QHash<QString, QString> metallicTextures;
QHash<QString, QString> roughnessTextures;
QHash<QString, QString> shininessTextures;
QHash<QString, FBXMaterial> _fbxMaterials;

View file

@ -100,17 +100,38 @@ void FBXReader::consolidateFBXMaterials() {
material.normalTexture = normalTexture;
detectDifferentUVs |= (normalTexture.texcoordSet != 0) || (!normalTexture.transform.isIdentity());
}
FBXTexture specularTexture;
QString specularTextureID = specularTextures.value(material.materialID);
if (!specularTextureID.isNull()) {
specularTexture = getTexture(specularTextureID);
detectDifferentUVs |= (specularTexture.texcoordSet != 0) || (!specularTexture.transform.isIdentity());
material.specularTexture = specularTexture;
}
FBXTexture metallicTexture;
QString metallicTextureID = metallicTextures.value(material.materialID);
if (!metallicTextureID.isNull()) {
metallicTexture = getTexture(metallicTextureID);
detectDifferentUVs |= (metallicTexture.texcoordSet != 0) || (!metallicTexture.transform.isIdentity());
material.metallicTexture = metallicTexture;
}
FBXTexture roughnessTexture;
QString roughnessTextureID = roughnessTextures.value(material.materialID);
QString shininessTextureID = shininessTextures.value(material.materialID);
if (!roughnessTextureID.isNull()) {
roughnessTexture = getTexture(roughnessTextureID);
roughnessTexture.isGlossmap = false;
material.roughnessTexture = roughnessTexture;
detectDifferentUVs |= (roughnessTexture.texcoordSet != 0) || (!roughnessTexture.transform.isIdentity());
} else if (!shininessTextureID.isNull()) {
roughnessTexture = getTexture(roughnessTextureID);
roughnessTexture.isGlossmap = true;
material.roughnessTexture = roughnessTexture;
detectDifferentUVs |= (roughnessTexture.texcoordSet != 0) || (!roughnessTexture.transform.isIdentity());
}
FBXTexture emissiveTexture;
glm::vec2 emissiveParams(0.f, 1.f);
emissiveParams.x = _lightmapOffset;
@ -142,11 +163,18 @@ void FBXReader::consolidateFBXMaterials() {
// diffuse *= material.diffuseFactor;
material._material->setAlbedo(diffuse);
float metallic = std::max(material.specularColor.x, std::max(material.specularColor.y, material.specularColor.z));
// FIXME: Do not use the Specular Factor yet as some FBX models have it set to 0
// metallic *= material.specularFactor;
material._material->setMetallic(metallic);
material._material->setGloss(material.shininess);
if (material.isPBSMaterial) {
material._material->setRoughness(material.roughness);
material._material->setMetallic(material.metallic);
} else {
material._material->setRoughness(model::Material::shininessToRoughness(material.shininess));
float metallic = std::max(material.specularColor.x, std::max(material.specularColor.y, material.specularColor.z));
// FIXME: Do not use the Specular Factor yet as some FBX models have it set to 0
// metallic *= material.specularFactor;
material._material->setMetallic(metallic);
}
if (material.opacity <= 0.0f) {
material._material->setOpacity(1.0f);

View file

@ -561,7 +561,7 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping,
modelMaterial->setEmissive(fbxMaterial.emissiveColor);
modelMaterial->setAlbedo(fbxMaterial.diffuseColor);
modelMaterial->setMetallic(glm::length(fbxMaterial.specularColor));
modelMaterial->setGloss(fbxMaterial.shininess);
modelMaterial->setRoughness(model::Material::shininessToRoughness(fbxMaterial.shininess));
if (fbxMaterial.opacity <= 0.0f) {
modelMaterial->setOpacity(1.0f);

View file

@ -58,12 +58,17 @@ void Material::setEmissive(const Color& emissive, bool isSRGB) {
_key.setEmissive(glm::any(glm::greaterThan(emissive, Color(0.0f))));
_schemaBuffer.edit<Schema>()._emissive = (isSRGB ? ColorUtils::toLinearVec3(emissive) : emissive);
}
/*
void Material::setGloss(float gloss) {
_key.setGloss((gloss > 0.0f));
_schemaBuffer.edit<Schema>()._gloss = gloss;
setRoughness(1.0 - gloss);
}*/
void Material::setRoughness(float roughness) {
roughness = std::min(1.0f, std::max(roughness, 0.0f));
_key.setGloss((roughness < 1.0f));
_schemaBuffer.edit<Schema>()._roughness = roughness;
}
void Material::setOpacity(float opacity) {
_key.setTransparent((opacity < 1.0f));
_schemaBuffer.edit<Schema>()._opacity = opacity;

View file

@ -229,8 +229,10 @@ public:
void setMetallic(float metallic);
float getMetallic() const { return _schemaBuffer.get<Schema>()._metallic.x; }
void setGloss(float gloss);
float getGloss() const { return _schemaBuffer.get<Schema>()._gloss; }
// void setGloss(float gloss);
void setRoughness(float gloss);
float getGloss() const { return 1.0f - getRoughness(); }
float getRoughness() const { return _schemaBuffer.get<Schema>()._roughness; }
void setOpacity(float opacity);
float getOpacity() const { return _schemaBuffer.get<Schema>()._opacity; }
@ -242,7 +244,7 @@ public:
glm::vec3 _albedo{ 0.5f };
float _opacity{1.f};
glm::vec3 _metallic{ 0.03f };
float _gloss{0.1f};
float _roughness{ 0.9f };
glm::vec3 _emissive{ 0.0f };
float _spare0{0.0f};
glm::vec4 _spareVec4{0.0f}; // for alignment beauty, Material size == Mat4x4
@ -256,6 +258,9 @@ public:
void setTextureMap(MapChannel channel, const TextureMapPointer& textureMap);
const TextureMaps& getTextureMaps() const { return _textureMaps; }
// conversion from previous properties to PBR equivalent
static float shininessToRoughness(float shininess) { return 1.0f - shininess / 128.0f; }
protected:
MaterialKey _key;

View file

@ -167,7 +167,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
if (normalMap && normalMap->isDefined()) {
batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, normalMap->getTextureView());
// texcoord are assumed to be the same has diffuse
// texcoord are assumed to be the same has albedo
} else {
batch.setResourceTexture(ShapePipeline::Slot::NORMAL_MAP, textureCache->getBlueTexture());
}
@ -181,7 +181,7 @@ void MeshPartPayload::bindMaterial(gpu::Batch& batch, const ShapePipeline::Locat
if (specularMap && specularMap->isDefined()) {
batch.setResourceTexture(ShapePipeline::Slot::SPECULAR_MAP, specularMap->getTextureView());
// texcoord are assumed to be the same has diffuse
// texcoord are assumed to be the same has albedo
} else {
batch.setResourceTexture(ShapePipeline::Slot::SPECULAR_MAP, textureCache->getBlackTexture());
}

View file

@ -1199,7 +1199,7 @@ void Model::segregateMeshGroups() {
_collisionHullMaterial = std::make_shared<model::Material>();
_collisionHullMaterial->setAlbedo(glm::vec3(1.0f, 0.5f, 0.0f));
_collisionHullMaterial->setMetallic(0.02f);
_collisionHullMaterial->setGloss(1.0f);
_collisionHullMaterial->setRoughness(0.5f);
}
_renderItemsSet << std::make_shared<MeshPartPayload>(networkMesh._mesh, partIndex, _collisionHullMaterial, transform, offset);
} else {

View file

@ -69,7 +69,7 @@ gpu::BufferView getDefaultMaterialBuffer() {
schema._albedo = vec3(1.0f);
schema._opacity = 1.0f;
schema._metallic = vec3(0.1f);
schema._gloss = 10.0f;
schema._roughness = 0.9f;
return gpu::BufferView(std::make_shared<gpu::Buffer>(sizeof(model::Material::Schema), (const gpu::Byte*) &schema));
}

View file

@ -15,7 +15,7 @@
<@include DeferredBufferWrite.slh@>
<@include model/Material.slh@>
// the diffuse texture
// the albedo texture
uniform sampler2D originalTexture;
// the interpolated normal

View file

@ -14,7 +14,7 @@
<@include DeferredBufferWrite.slh@>
// the diffuse texture
// the albedo texture
uniform sampler2D originalTexture;
// the interpolated normal