Standardise Clearcoat, Sheen and Transmission

Also cleanup glTFv2 defaults, don't import/export if disabled
pull/3952/head
RichardTea 2021-06-11 13:44:52 +01:00
parent 9f9d77f882
commit 4b4d6b1326
7 changed files with 281 additions and 152 deletions

View File

@ -436,11 +436,11 @@ inline void SetSamplerWrap(SamplerWrap& wrap, aiTextureMapMode map)
};
}
void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref<Texture> texture, aiTextureType tt, unsigned int slot)
void glTF2Exporter::GetTexSampler(const aiMaterial& mat, Ref<Texture> texture, aiTextureType tt, unsigned int slot)
{
aiString aId;
std::string id;
if (aiGetMaterialString(mat, AI_MATKEY_GLTF_MAPPINGID(tt, slot), &aId) == AI_SUCCESS) {
if (aiGetMaterialString(&mat, AI_MATKEY_GLTF_MAPPINGID(tt, slot), &aId) == AI_SUCCESS) {
id = aId.C_Str();
}
@ -455,49 +455,49 @@ void glTF2Exporter::GetTexSampler(const aiMaterial* mat, Ref<Texture> texture, a
SamplerMagFilter filterMag;
SamplerMinFilter filterMin;
if (aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_U(tt, slot), (int*)&mapU) == AI_SUCCESS) {
if (aiGetMaterialInteger(&mat, AI_MATKEY_MAPPINGMODE_U(tt, slot), (int*)&mapU) == AI_SUCCESS) {
SetSamplerWrap(texture->sampler->wrapS, mapU);
}
if (aiGetMaterialInteger(mat, AI_MATKEY_MAPPINGMODE_V(tt, slot), (int*)&mapV) == AI_SUCCESS) {
if (aiGetMaterialInteger(&mat, AI_MATKEY_MAPPINGMODE_V(tt, slot), (int*)&mapV) == AI_SUCCESS) {
SetSamplerWrap(texture->sampler->wrapT, mapV);
}
if (aiGetMaterialInteger(mat, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(tt, slot), (int*)&filterMag) == AI_SUCCESS) {
if (aiGetMaterialInteger(&mat, AI_MATKEY_GLTF_MAPPINGFILTER_MAG(tt, slot), (int*)&filterMag) == AI_SUCCESS) {
texture->sampler->magFilter = filterMag;
}
if (aiGetMaterialInteger(mat, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(tt, slot), (int*)&filterMin) == AI_SUCCESS) {
if (aiGetMaterialInteger(&mat, AI_MATKEY_GLTF_MAPPINGFILTER_MIN(tt, slot), (int*)&filterMin) == AI_SUCCESS) {
texture->sampler->minFilter = filterMin;
}
aiString name;
if (aiGetMaterialString(mat, AI_MATKEY_GLTF_MAPPINGNAME(tt, slot), &name) == AI_SUCCESS) {
if (aiGetMaterialString(&mat, AI_MATKEY_GLTF_MAPPINGNAME(tt, slot), &name) == AI_SUCCESS) {
texture->sampler->name = name.C_Str();
}
}
}
void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int slot)
void glTF2Exporter::GetMatTexProp(const aiMaterial& mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int slot)
{
std::string textureKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName;
mat->Get(textureKey.c_str(), tt, slot, prop);
mat.Get(textureKey.c_str(), tt, slot, prop);
}
void glTF2Exporter::GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int slot)
void glTF2Exporter::GetMatTexProp(const aiMaterial& mat, float& prop, const char* propName, aiTextureType tt, unsigned int slot)
{
std::string textureKey = std::string(_AI_MATKEY_TEXTURE_BASE) + "." + propName;
mat->Get(textureKey.c_str(), tt, slot, prop);
mat.Get(textureKey.c_str(), tt, slot, prop);
}
void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTextureType tt, unsigned int slot = 0)
void glTF2Exporter::GetMatTex(const aiMaterial& mat, Ref<Texture>& texture, aiTextureType tt, unsigned int slot = 0)
{
if (mat->GetTextureCount(tt) > 0) {
if (mat.GetTextureCount(tt) > 0) {
aiString tex;
if (mat->Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) {
if (mat.Get(AI_MATKEY_TEXTURE(tt, slot), tex) == AI_SUCCESS) {
std::string path = tex.C_Str();
if (path.size() > 0) {
@ -568,7 +568,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, Ref<Texture>& texture, aiTe
}
}
void glTF2Exporter::GetMatTex(const aiMaterial* mat, TextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
void glTF2Exporter::GetMatTex(const aiMaterial& mat, TextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
{
Ref<Texture>& texture = prop.texture;
@ -579,7 +579,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, TextureInfo& prop, aiTextur
}
}
void glTF2Exporter::GetMatTex(const aiMaterial* mat, NormalTextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
void glTF2Exporter::GetMatTex(const aiMaterial& mat, NormalTextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
{
Ref<Texture>& texture = prop.texture;
@ -591,7 +591,7 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, NormalTextureInfo& prop, ai
}
}
void glTF2Exporter::GetMatTex(const aiMaterial* mat, OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
void glTF2Exporter::GetMatTex(const aiMaterial& mat, OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot = 0)
{
Ref<Texture>& texture = prop.texture;
@ -603,10 +603,10 @@ void glTF2Exporter::GetMatTex(const aiMaterial* mat, OcclusionTextureInfo& prop,
}
}
aiReturn glTF2Exporter::GetMatColor(const aiMaterial* mat, vec4& prop, const char* propName, int type, int idx)
aiReturn glTF2Exporter::GetMatColor(const aiMaterial& mat, vec4& prop, const char* propName, int type, int idx) const
{
aiColor4D col;
aiReturn result = mat->Get(propName, type, idx, col);
aiReturn result = mat.Get(propName, type, idx, col);
if (result == AI_SUCCESS) {
prop[0] = col.r; prop[1] = col.g; prop[2] = col.b; prop[3] = col.a;
@ -615,30 +615,109 @@ aiReturn glTF2Exporter::GetMatColor(const aiMaterial* mat, vec4& prop, const cha
return result;
}
aiReturn glTF2Exporter::GetMatColor(const aiMaterial* mat, vec3& prop, const char* propName, int type, int idx)
aiReturn glTF2Exporter::GetMatColor(const aiMaterial& mat, vec3& prop, const char* propName, int type, int idx) const
{
aiColor3D col;
aiReturn result = mat->Get(propName, type, idx, col);
aiReturn result = mat.Get(propName, type, idx, col);
if (result == AI_SUCCESS) {
prop[0] = col.r; prop[1] = col.g; prop[2] = col.b;
prop[0] = col.r;
prop[1] = col.g;
prop[2] = col.b;
}
return result;
}
bool glTF2Exporter::GetMatSpecGloss(const aiMaterial &mat, glTF2::PbrSpecularGlossiness &pbrSG) {
bool result = false;
// If has Glossiness, a Specular Color or Specular Texture, use the KHR_materials_pbrSpecularGlossiness extension
// NOTE: This extension is being considered for deprecation (Dec 2020), may be replaced by KHR_material_specular
if (mat.Get(AI_MATKEY_GLOSSINESS_FACTOR, pbrSG.glossinessFactor) == AI_SUCCESS) {
result = true;
} else {
// Don't have explicit glossiness, convert from pbr roughness or legacy shininess
float shininess;
if (mat.Get(AI_MATKEY_ROUGHNESS_FACTOR, shininess) == AI_SUCCESS) {
pbrSG.glossinessFactor = 1.0f - shininess; // Extension defines this way
} else if (mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
pbrSG.glossinessFactor = shininess / 1000;
}
}
if (GetMatColor(mat, pbrSG.specularFactor, AI_MATKEY_COLOR_SPECULAR) == AI_SUCCESS) {
result = true;
}
// Add any appropriate textures
GetMatTex(mat, pbrSG.specularGlossinessTexture, aiTextureType_SPECULAR);
result == result || pbrSG.specularGlossinessTexture.texture;
if (result) {
// Likely to always have diffuse
GetMatTex(mat, pbrSG.diffuseTexture, aiTextureType_DIFFUSE);
GetMatColor(mat, pbrSG.diffuseFactor, AI_MATKEY_COLOR_DIFFUSE);
}
return result;
}
bool glTF2Exporter::GetMatSheen(const aiMaterial &mat, glTF2::MaterialSheen &sheen) {
// Return true if got any valid Sheen properties or textures
if (GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_SHEEN_COLOR_FACTOR) != aiReturn_SUCCESS)
return false;
// Default Sheen color factor {0,0,0} disables Sheen, so do not export
if (sheen.sheenColorFactor == defaultSheenFactor)
return false;
mat.Get(AI_MATKEY_SHEEN_ROUGHNESS_FACTOR, sheen.sheenRoughnessFactor);
GetMatTex(mat, sheen.sheenColorTexture, AI_MATKEY_SHEEN_COLOR_TEXTURE);
GetMatTex(mat, sheen.sheenRoughnessTexture, AI_MATKEY_SHEEN_ROUGHNESS_TEXTURE);
return true;
}
bool glTF2Exporter::GetMatClearcoat(const aiMaterial &mat, glTF2::MaterialClearcoat &clearcoat) {
if (mat.Get(AI_MATKEY_CLEARCOAT_FACTOR, clearcoat.clearcoatFactor) != aiReturn_SUCCESS) {
return false;
}
// Clearcoat factor of zero disables Clearcoat, so do not export
if (clearcoat.clearcoatFactor == 0.0f)
return false;
mat.Get(AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR, clearcoat.clearcoatRoughnessFactor);
GetMatTex(mat, clearcoat.clearcoatTexture, AI_MATKEY_CLEARCOAT_TEXTURE);
GetMatTex(mat, clearcoat.clearcoatRoughnessTexture, AI_MATKEY_CLEARCOAT_ROUGHNESS_TEXTURE);
GetMatTex(mat, clearcoat.clearcoatNormalTexture, AI_MATKEY_CLEARCOAT_NORMAL_TEXTURE);
return true;
}
bool glTF2Exporter::GetMatTransmission(const aiMaterial &mat, glTF2::MaterialTransmission &transmission) {
bool result = mat.Get(AI_MATKEY_TRANSMISSION_FACTOR, transmission.transmissionFactor) == aiReturn_SUCCESS;
GetMatTex(mat, transmission.transmissionTexture, AI_MATKEY_TRANSMISSION_TEXTURE);
return result || transmission.transmissionTexture.texture;
}
void glTF2Exporter::ExportMaterials()
{
aiString aiName;
for (unsigned int i = 0; i < mScene->mNumMaterials; ++i) {
const aiMaterial* mat = mScene->mMaterials[i];
ai_assert(mScene->mMaterials[i] != nullptr);
const aiMaterial & mat = *(mScene->mMaterials[i]);
std::string id = "material_" + ai_to_string(i);
Ref<Material> m = mAsset->materials.Create(id);
std::string name;
if (mat->Get(AI_MATKEY_NAME, aiName) == AI_SUCCESS) {
if (mat.Get(AI_MATKEY_NAME, aiName) == AI_SUCCESS) {
name = aiName.C_Str();
}
name = mAsset->FindUniqueID(name, "material");
@ -660,20 +739,20 @@ void glTF2Exporter::ExportMaterials()
GetMatColor(mat, m->pbrMetallicRoughness.baseColorFactor, AI_MATKEY_COLOR_DIFFUSE);
}
if (mat->Get(AI_MATKEY_METALLIC_FACTOR, m->pbrMetallicRoughness.metallicFactor) != AI_SUCCESS) {
if (mat.Get(AI_MATKEY_METALLIC_FACTOR, m->pbrMetallicRoughness.metallicFactor) != AI_SUCCESS) {
//if metallicFactor wasn't defined, then the source is likely not a PBR file, and the metallicFactor should be 0
m->pbrMetallicRoughness.metallicFactor = 0;
}
// get roughness if source is gltf2 file
if (mat->Get(AI_MATKEY_ROUGHNESS_FACTOR, m->pbrMetallicRoughness.roughnessFactor) != AI_SUCCESS) {
if (mat.Get(AI_MATKEY_ROUGHNESS_FACTOR, m->pbrMetallicRoughness.roughnessFactor) != AI_SUCCESS) {
// otherwise, try to derive and convert from specular + shininess values
aiColor4D specularColor;
ai_real shininess;
if (
mat->Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS &&
mat->Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS
mat.Get(AI_MATKEY_COLOR_SPECULAR, specularColor) == AI_SUCCESS &&
mat.Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS
) {
// convert specular color to luminance
float specularIntensity = specularColor[0] * 0.2125f + specularColor[1] * 0.7154f + specularColor[2] * 0.0721f;
@ -694,17 +773,17 @@ void glTF2Exporter::ExportMaterials()
GetMatTex(mat, m->emissiveTexture, aiTextureType_EMISSIVE);
GetMatColor(mat, m->emissiveFactor, AI_MATKEY_COLOR_EMISSIVE);
mat->Get(AI_MATKEY_TWOSIDED, m->doubleSided);
mat->Get(AI_MATKEY_GLTF_ALPHACUTOFF, m->alphaCutoff);
mat.Get(AI_MATKEY_TWOSIDED, m->doubleSided);
mat.Get(AI_MATKEY_GLTF_ALPHACUTOFF, m->alphaCutoff);
aiString alphaMode;
if (mat->Get(AI_MATKEY_GLTF_ALPHAMODE, alphaMode) == AI_SUCCESS) {
if (mat.Get(AI_MATKEY_GLTF_ALPHAMODE, alphaMode) == AI_SUCCESS) {
m->alphaMode = alphaMode.C_Str();
} else {
float opacity;
if (mat->Get(AI_MATKEY_OPACITY, opacity) == AI_SUCCESS) {
if (mat.Get(AI_MATKEY_OPACITY, opacity) == AI_SUCCESS) {
if (opacity < 1) {
m->alphaMode = "BLEND";
m->pbrMetallicRoughness.baseColorFactor[3] *= opacity;
@ -713,86 +792,43 @@ void glTF2Exporter::ExportMaterials()
}
{
// If has a Specular color, use the KHR_materials_pbrSpecularGlossiness extension
// KHR_materials_pbrSpecularGlossiness extension
// NOTE: This extension is being considered for deprecation (Dec 2020)
PbrSpecularGlossiness pbrSG;
if (GetMatColor(mat, pbrSG.specularFactor, AI_MATKEY_COLOR_SPECULAR) == AI_SUCCESS) {
if (!mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness) {
mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness = true;
}
GetMatColor(mat, pbrSG.diffuseFactor, AI_MATKEY_COLOR_DIFFUSE);
// If don't have explicit glossiness then convert from roughness or shininess
if (mat->Get(AI_MATKEY_GLOSSINESS_FACTOR, pbrSG.glossinessFactor) != AI_SUCCESS) {
float shininess;
if (mat->Get(AI_MATKEY_ROUGHNESS_FACTOR, shininess) == AI_SUCCESS) {
pbrSG.glossinessFactor = 1.0f - shininess; // Extension defines this way
} else if (mat->Get(AI_MATKEY_SHININESS, shininess) == AI_SUCCESS) {
pbrSG.glossinessFactor = shininess / 1000;
}
}
// Add any appropriate textures
GetMatTex(mat, pbrSG.diffuseTexture, aiTextureType_DIFFUSE);
GetMatTex(mat, pbrSG.specularGlossinessTexture, aiTextureType_SPECULAR);
if (GetMatSpecGloss(mat, pbrSG)) {
mAsset->extensionsUsed.KHR_materials_pbrSpecularGlossiness = true;
m->pbrSpecularGlossiness = Nullable<PbrSpecularGlossiness>(pbrSG);
}
}
// glTFv2 is either PBR or Unlit
aiShadingMode shadingMode = aiShadingMode_PBR_BRDF;
mat->Get(AI_MATKEY_SHADING_MODEL, shadingMode);
mat.Get(AI_MATKEY_SHADING_MODEL, shadingMode);
if (shadingMode == aiShadingMode_Unlit) {
mAsset->extensionsUsed.KHR_materials_unlit = true;
m->unlit = true;
}
} else {
// These extensions are not compatible with KHR_materials_unlit or KHR_materials_pbrSpecularGlossiness
if (!m->pbrSpecularGlossiness.isPresent) {
// Sheen
MaterialSheen sheen;
if (GetMatSheen(mat, sheen)) {
mAsset->extensionsUsed.KHR_materials_sheen = true;
m->materialSheen = Nullable<MaterialSheen>(sheen);
}
bool hasMaterialSheen = false;
mat->Get(AI_MATKEY_GLTF_MATERIAL_SHEEN, hasMaterialSheen);
MaterialClearcoat clearcoat;
if (GetMatClearcoat(mat, clearcoat)) {
mAsset->extensionsUsed.KHR_materials_clearcoat = true;
m->materialClearcoat = Nullable<MaterialClearcoat>(clearcoat);
}
if (hasMaterialSheen) {
mAsset->extensionsUsed.KHR_materials_sheen = true;
MaterialSheen sheen;
GetMatColor(mat, sheen.sheenColorFactor, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR);
mat->Get(AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR, sheen.sheenRoughnessFactor);
GetMatTex(mat, sheen.sheenColorTexture, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE);
GetMatTex(mat, sheen.sheenRoughnessTexture, AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE);
m->materialSheen = Nullable<MaterialSheen>(sheen);
}
bool hasMaterialClearcoat = false;
mat->Get(AI_MATKEY_GLTF_MATERIAL_CLEARCOAT, hasMaterialClearcoat);
if (hasMaterialClearcoat) {
mAsset->extensionsUsed.KHR_materials_clearcoat= true;
MaterialClearcoat clearcoat;
mat->Get(AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR, clearcoat.clearcoatFactor);
mat->Get(AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR, clearcoat.clearcoatRoughnessFactor);
GetMatTex(mat, clearcoat.clearcoatTexture, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE);
GetMatTex(mat, clearcoat.clearcoatRoughnessTexture, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE);
GetMatTex(mat, clearcoat.clearcoatNormalTexture, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE);
m->materialClearcoat = Nullable<MaterialClearcoat>(clearcoat);
}
bool hasMaterialTransmission = false;
mat->Get(AI_MATKEY_GLTF_MATERIAL_TRANSMISSION, hasMaterialTransmission);
if (hasMaterialTransmission) {
mAsset->extensionsUsed.KHR_materials_transmission = true;
MaterialTransmission transmission;
mat->Get(AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR, transmission.transmissionFactor);
GetMatTex(mat, transmission.transmissionTexture, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE);
m->materialTransmission = Nullable<MaterialTransmission>(transmission);
MaterialTransmission transmission;
if (GetMatTransmission(mat, transmission)) {
mAsset->extensionsUsed.KHR_materials_transmission = true;
m->materialTransmission = Nullable<MaterialTransmission>(transmission);
}
}
}
}
}

View File

@ -72,6 +72,10 @@ namespace glTF2
struct OcclusionTextureInfo;
struct Node;
struct Texture;
struct PbrSpecularGlossiness;
struct MaterialSheen;
struct MaterialClearcoat;
struct MaterialTransmission;
// Vec/matrix types, as raw float arrays
typedef float (vec2)[2];
@ -97,15 +101,19 @@ namespace Assimp
protected:
void WriteBinaryData(IOStream* outfile, std::size_t sceneLength);
void GetTexSampler(const aiMaterial* mat, glTF2::Ref<glTF2::Texture> texture, aiTextureType tt, unsigned int slot);
void GetMatTexProp(const aiMaterial* mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int idx);
void GetMatTexProp(const aiMaterial* mat, float& prop, const char* propName, aiTextureType tt, unsigned int idx);
void GetMatTex(const aiMaterial* mat, glTF2::Ref<glTF2::Texture>& texture, aiTextureType tt, unsigned int slot);
void GetMatTex(const aiMaterial* mat, glTF2::TextureInfo& prop, aiTextureType tt, unsigned int slot);
void GetMatTex(const aiMaterial* mat, glTF2::NormalTextureInfo& prop, aiTextureType tt, unsigned int slot);
void GetMatTex(const aiMaterial* mat, glTF2::OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot);
aiReturn GetMatColor(const aiMaterial* mat, glTF2::vec4& prop, const char* propName, int type, int idx);
aiReturn GetMatColor(const aiMaterial* mat, glTF2::vec3& prop, const char* propName, int type, int idx);
void GetTexSampler(const aiMaterial& mat, glTF2::Ref<glTF2::Texture> texture, aiTextureType tt, unsigned int slot);
void GetMatTexProp(const aiMaterial& mat, unsigned int& prop, const char* propName, aiTextureType tt, unsigned int idx);
void GetMatTexProp(const aiMaterial& mat, float& prop, const char* propName, aiTextureType tt, unsigned int idx);
void GetMatTex(const aiMaterial& mat, glTF2::Ref<glTF2::Texture>& texture, aiTextureType tt, unsigned int slot);
void GetMatTex(const aiMaterial& mat, glTF2::TextureInfo& prop, aiTextureType tt, unsigned int slot);
void GetMatTex(const aiMaterial& mat, glTF2::NormalTextureInfo& prop, aiTextureType tt, unsigned int slot);
void GetMatTex(const aiMaterial& mat, glTF2::OcclusionTextureInfo& prop, aiTextureType tt, unsigned int slot);
aiReturn GetMatColor(const aiMaterial& mat, glTF2::vec4& prop, const char* propName, int type, int idx) const;
aiReturn GetMatColor(const aiMaterial& mat, glTF2::vec3& prop, const char* propName, int type, int idx) const;
bool GetMatSpecGloss(const aiMaterial& mat, glTF2::PbrSpecularGlossiness& pbrSG);
bool GetMatSheen(const aiMaterial& mat, glTF2::MaterialSheen& sheen);
bool GetMatClearcoat(const aiMaterial& mat, glTF2::MaterialClearcoat& clearcoat);
bool GetMatTransmission(const aiMaterial& mat, glTF2::MaterialTransmission& transmission);
void ExportMetadata();
void ExportMaterials();
void ExportMeshes();

View File

@ -291,36 +291,37 @@ static aiMaterial *ImportMaterial(std::vector<int> &embeddedTexIdxs, Asset &r, M
aimat->AddProperty(&shadingMode, 1, AI_MATKEY_SHADING_MODEL);
//KHR_materials_sheen
// KHR_materials_sheen
if (mat.materialSheen.isPresent) {
MaterialSheen &sheen = mat.materialSheen.value;
aimat->AddProperty(&mat.materialSheen.isPresent, 1, AI_MATKEY_GLTF_MATERIAL_SHEEN);
SetMaterialColorProperty(r, sheen.sheenColorFactor, aimat, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR);
aimat->AddProperty(&sheen.sheenRoughnessFactor, 1, AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR);
SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenColorTexture, aimat, AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE);
SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenRoughnessTexture, aimat, AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE);
// Default value {0,0,0} disables Sheen
if (sheen.sheenColorFactor != defaultSheenFactor) {
SetMaterialColorProperty(r, sheen.sheenColorFactor, aimat, AI_MATKEY_SHEEN_COLOR_FACTOR);
aimat->AddProperty(&sheen.sheenRoughnessFactor, 1, AI_MATKEY_SHEEN_ROUGHNESS_FACTOR);
SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenColorTexture, aimat, AI_MATKEY_SHEEN_COLOR_TEXTURE);
SetMaterialTextureProperty(embeddedTexIdxs, r, sheen.sheenRoughnessTexture, aimat, AI_MATKEY_SHEEN_ROUGHNESS_TEXTURE);
}
}
//KHR_materials_clearcoat
// KHR_materials_clearcoat
if (mat.materialClearcoat.isPresent) {
MaterialClearcoat &clearcoat = mat.materialClearcoat.value;
aimat->AddProperty(&mat.materialClearcoat.isPresent, 1, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT);
aimat->AddProperty(&clearcoat.clearcoatFactor, 1, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR);
aimat->AddProperty(&clearcoat.clearcoatRoughnessFactor, 1, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR);
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatTexture, aimat, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE);
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatRoughnessTexture, aimat, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE);
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatNormalTexture, aimat, AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE);
// Default value 0.0 disables clearcoat
if (clearcoat.clearcoatFactor != 0.0f) {
aimat->AddProperty(&clearcoat.clearcoatFactor, 1, AI_MATKEY_CLEARCOAT_FACTOR);
aimat->AddProperty(&clearcoat.clearcoatRoughnessFactor, 1, AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR);
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatTexture, aimat, AI_MATKEY_CLEARCOAT_TEXTURE);
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatRoughnessTexture, aimat, AI_MATKEY_CLEARCOAT_ROUGHNESS_TEXTURE);
SetMaterialTextureProperty(embeddedTexIdxs, r, clearcoat.clearcoatNormalTexture, aimat, AI_MATKEY_CLEARCOAT_NORMAL_TEXTURE);
}
}
//KHR_materials_transmission
// KHR_materials_transmission
if (mat.materialTransmission.isPresent) {
MaterialTransmission &transmission = mat.materialTransmission.value;
aimat->AddProperty(&mat.materialTransmission.isPresent, 1, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION);
aimat->AddProperty(&transmission.transmissionFactor, 1, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR);
SetMaterialTextureProperty(embeddedTexIdxs, r, transmission.transmissionTexture, aimat, AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE);
aimat->AddProperty(&transmission.transmissionFactor, 1, AI_MATKEY_TRANSMISSION_FACTOR);
SetMaterialTextureProperty(embeddedTexIdxs, r, transmission.transmissionTexture, aimat, AI_MATKEY_TRANSMISSION_TEXTURE);
}
return aimat;

View File

@ -47,10 +47,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include <assimp/material.h>
// -------------------------------------------------------------------------------
const char* TextureTypeToString(aiTextureType in)
{
switch (in)
{
const char *TextureTypeToString(aiTextureType in) {
switch (in) {
case aiTextureType_NONE:
return "n/a";
case aiTextureType_DIFFUSE:
@ -87,6 +85,12 @@ const char* TextureTypeToString(aiTextureType in)
return "DiffuseRoughness";
case aiTextureType_AMBIENT_OCCLUSION:
return "AmbientOcclusion";
case aiTextureType_SHEEN:
return "Sheen";
case aiTextureType_CLEARCOAT:
return "Clearcoat";
case aiTextureType_TRANSMISSION:
return "Transmission";
case aiTextureType_UNKNOWN:
return "Unknown";
default:

View File

@ -144,7 +144,9 @@ enum aiTextureMapMode {
enum aiTextureMapping {
/** The mapping coordinates are taken from an UV channel.
*
* The #AI_MATKEY_UVWSRC key specifies from which UV channel
* #AI_MATKEY_UVWSRC property
*
* Specifies from which UV channel
* the texture coordinates are to be taken from (remember,
* meshes can have more than one UV channel).
*/
@ -292,6 +294,32 @@ enum aiTextureType {
aiTextureType_DIFFUSE_ROUGHNESS = 16,
aiTextureType_AMBIENT_OCCLUSION = 17,
/** PBR Material Modifiers
* Some modern renderers have further PBR modifiers that may be overlaid
* on top of the 'base' PBR materials for additional realism.
* These use multiple texture maps, so only the base type is directly defined
*/
/** Sheen
* Generally used to simulate textiles that are covered in a layer of microfibers
* eg velvet
* https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_sheen
*/
aiTextureType_SHEEN = 19,
/** Clearcoat
* Simulates a layer of 'polish' or 'laquer' layered on top of a PBR substrate
* https://autodesk.github.io/standard-surface/#closures/coating
* https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_clearcoat
*/
aiTextureType_CLEARCOAT = 20,
/** Transmission
* Simulates transmission through the surface
* May include further information such as wall thickness
*/
aiTextureType_TRANSMISSION = 21,
/** Unknown texture
*
* A texture reference that does not match any of the definitions
@ -314,7 +342,7 @@ ASSIMP_API const char *TextureTypeToString(enum aiTextureType in);
// ---------------------------------------------------------------------------
/** @brief Defines all shading models supported by the library
*
* #AI_MATKEY_SHADING_MODEL
* Property: #AI_MATKEY_SHADING_MODEL
*
* The list of shading modes has been taken from Blender.
* See Blender documentation for more information. The API does
@ -324,6 +352,7 @@ ASSIMP_API const char *TextureTypeToString(enum aiTextureType in);
* Again, this value is just a hint. Assimp tries to select the shader whose
* most common implementation matches the original rendering results of the
* 3D modeler which wrote a particular model as closely as possible.
*
*/
enum aiShadingMode {
/** Flat shading. Shading is done on per-face base,
@ -384,10 +413,11 @@ enum aiShadingMode {
* There are multiple methods under this banner, and model files may provide
* data for more than one PBR-BRDF method.
* Applications should use the set of provided properties to determine which
* of their preferred PBDR methods are available
* of their preferred PBR rendering methods are likely to be available
* eg:
* - If AI_MATKEY_METALLIC_FACTOR is set, then a Metallic/Roughness is available
* - If AI_MATKEY_COLOR_SPECULAR is set, then a Specular/Glossiness is available
* - If AI_MATKEY_GLOSSINESS_FACTOR is set, then a Specular/Glossiness is available
* Note that some PBR methods allow layering of techniques
*/
aiShadingMode_PBR_BRDF = 0xb,
@ -942,28 +972,63 @@ extern "C" {
// ---------------------------------------------------------------------------
// PBR material support
// --------------------
// Properties defining PBR rendering techniques
#define AI_MATKEY_USE_COLOR_MAP "$mat.useColorMap", 0, 0
// Metallic/Roughness Workflow
// ---------------------------
// Base color factor. Will be multiplied by final base color texture values if extant
// Base RGBA color factor. Will be multiplied by final base color texture values if extant
// Note: Importers may choose to copy this into AI_MATKEY_COLOR_DIFFUSE for compatibility
// with renderers and formats that do not support Metallic/Roughness PBR
#define AI_MATKEY_BASE_COLOR "$clr.base", 0, 0
#define AI_MATKEY_BASE_COLOR_TEXTURE aiTextureType_BASE_COLOR, 0
#define AI_MATKEY_USE_METALLIC_MAP "$mat.useMetallicMap", 0, 0
// Metallic factor. 0.0 = Full Dielectric, 1.0 = Full Metal
#define AI_MATKEY_METALLIC_FACTOR "$mat.metallicFactor", 0, 0
#define AI_MATKEY_METALLIC_TEXTURE aiTextureType_METALNESS, 0
#define AI_MATKEY_USE_ROUGHNESS_MAP "$mat.useRoughnessMap", 0, 0
// Roughness factor. 0.0 = Perfectly Smooth, 1.0 = Completely Rough
#define AI_MATKEY_ROUGHNESS_FACTOR "$mat.roughnessFactor", 0, 0
#define AI_MATKEY_ROUGHNESS_TEXTURE aiTextureType_DIFFUSE_ROUGHNESS, 0
// Specular/Glossiness Workflow
// ---------------------------
// Diffuse/Albedo Color. Note: Pure Metals have a diffuse of {0,0,0}
// AI_MATKEY_COLOR_DIFFUSE
// Specular Color
// Specular Color.
// Note: Metallic/Roughness may also have a Specular Color
// AI_MATKEY_COLOR_SPECULAR
#define AI_MATKEY_SPECULAR_FACTOR "$mat.specularFactor", 0, 0
// Glossiness factor. 0.0 = Completely Rough, 1.0 = Perfectly Smooth
#define AI_MATKEY_GLOSSINESS_FACTOR "$mat.glossinessFactor", 0, 0
// Sheen
// -----
// Sheen base RGB color. Default {0,0,0}
#define AI_MATKEY_SHEEN_COLOR_FACTOR "$clr.sheen.factor", 0, 0
// Sheen Roughness Factor.
#define AI_MATKEY_SHEEN_ROUGHNESS_FACTOR "$mat.sheen.roughnessFactor", 0, 0
#define AI_MATKEY_SHEEN_COLOR_TEXTURE aiTextureType_SHEEN, 0
#define AI_MATKEY_SHEEN_ROUGHNESS_TEXTURE aiTextureType_SHEEN, 1
// Clearcoat
// ---------
#define AI_MATKEY_CLEARCOAT_FACTOR "$clr.clearcoat.factor", 0, 0
#define AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR "$mat.clearcoat.roughnessFactor", 0, 0
#define AI_MATKEY_CLEARCOAT_TEXTURE aiTextureType_CLEARCOAT, 0
#define AI_MATKEY_CLEARCOAT_ROUGHNESS_TEXTURE aiTextureType_CLEARCOAT, 1
#define AI_MATKEY_CLEARCOAT_NORMAL_TEXTURE aiTextureType_CLEARCOAT, 2
// Transmission
// ------------
// https://github.com/KhronosGroup/glTF/tree/master/extensions/2.0/Khronos/KHR_materials_transmission
// Base percentage of light transmitted through the surface. 0.0 = Opaque, 1.0 = Fully transparent
#define AI_MATKEY_TRANSMISSION_FACTOR "$mat.transmission.factor", 0, 0
// Texture defining percentage of light transmitted through the surface.
// Multiplied by AI_MATKEY_TRANSMISSION_FACTOR
#define AI_MATKEY_TRANSMISSION_TEXTURE aiTextureType_TRANSMISSION, 0
// Emissive
// --------
#define AI_MATKEY_USE_EMISSIVE_MAP "$mat.useEmissiveMap", 0, 0

View File

@ -60,20 +60,20 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS "$mat.gltf.pbrSpecularGlossiness", 0, 0
//#define AI_MATKEY_GLTF_PBRSPECULARGLOSSINESS_GLOSSINESS_FACTOR "$mat.gltf.pbrMetallicRoughness.glossinessFactor", 0, 0
//#define AI_MATKEY_GLTF_UNLIT "$mat.gltf.unlit", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_SHEEN "$mat.gltf.materialSheen", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR "$mat.gltf.materialSheen.sheenColorFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR "$mat.gltf.materialSheen.sheenRoughnessFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE aiTextureType_UNKNOWN, 1
#define AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 2
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT "$mat.gltf.materialClearcoat", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR "$mat.gltf.materialClearcoat.clearcoatFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR "$mat.gltf.materialClearcoat.clearcoatRoughnessFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE aiTextureType_UNKNOWN, 3
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 4
#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE aiTextureType_NORMALS, 1
#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION "$mat.gltf.materialTransmission", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR "$mat.gltf.materialTransmission.transmissionFactor", 0, 0
#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE aiTextureType_UNKNOWN, 5
//#define AI_MATKEY_GLTF_MATERIAL_SHEEN "$mat.gltf.materialSheen", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_FACTOR "$mat.gltf.materialSheen.sheenColorFactor", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_FACTOR "$mat.gltf.materialSheen.sheenRoughnessFactor", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_SHEEN_COLOR_TEXTURE aiTextureType_UNKNOWN, 1
//#define AI_MATKEY_GLTF_MATERIAL_SHEEN_ROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 2
//#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT "$mat.gltf.materialClearcoat", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_FACTOR "$mat.gltf.materialClearcoat.clearcoatFactor", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_FACTOR "$mat.gltf.materialClearcoat.clearcoatRoughnessFactor", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_TEXTURE aiTextureType_UNKNOWN, 3
//#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_ROUGHNESS_TEXTURE aiTextureType_UNKNOWN, 4
//#define AI_MATKEY_GLTF_MATERIAL_CLEARCOAT_NORMAL_TEXTURE aiTextureType_NORMALS, 1
//#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION "$mat.gltf.materialTransmission", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_FACTOR "$mat.gltf.materialTransmission.transmissionFactor", 0, 0
//#define AI_MATKEY_GLTF_MATERIAL_TRANSMISSION_TEXTURE aiTextureType_UNKNOWN, 5
#define _AI_MATKEY_GLTF_TEXTURE_TEXCOORD_BASE "$tex.file.texCoord"
#define _AI_MATKEY_GLTF_MAPPINGNAME_BASE "$tex.mappingname"

View File

@ -152,6 +152,20 @@ TEST_F(utglTF2ImportExport, importglTF2_KHR_materials_pbrSpecularGlossiness) {
}
#ifndef ASSIMP_BUILD_NO_EXPORT
TEST_F(utglTF2ImportExport, importglTF2AndExport_KHR_materials_pbrSpecularGlossiness) {
Assimp::Importer importer;
Assimp::Exporter exporter;
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured.gltf",
aiProcess_ValidateDataStructure);
EXPECT_NE(nullptr, scene);
// Export
EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "glb2", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured_out.glb"));
// And re-import
EXPECT_TRUE(importerMatTest(ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-pbrSpecularGlossiness/BoxTextured_out.glb", true));
}
TEST_F(utglTF2ImportExport, importglTF2AndExportToOBJ) {
Assimp::Importer importer;
Assimp::Exporter exporter;
@ -169,6 +183,7 @@ TEST_F(utglTF2ImportExport, importglTF2EmbeddedAndExportToOBJ) {
EXPECT_NE(nullptr, scene);
EXPECT_EQ(aiReturn_SUCCESS, exporter.Export(scene, "obj", ASSIMP_TEST_MODELS_DIR "/glTF2/BoxTextured-glTF-Embedded/BoxTextured_out.obj"));
}
#endif // ASSIMP_BUILD_NO_EXPORT
TEST_F(utglTF2ImportExport, importglTF2PrimitiveModePointsWithoutIndices) {