Skip to content

Commit c2375a4

Browse files
authored
Merge pull request #4272 from errissa/pbr-obj
Support PBR properties/maps in Obj importer
2 parents 049a241 + ab19cff commit c2375a4

File tree

4 files changed

+131
-1
lines changed

4 files changed

+131
-1
lines changed

code/AssetLib/Obj/ObjFileData.h

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,10 @@ struct Material {
133133
aiString textureSpecularity;
134134
aiString textureOpacity;
135135
aiString textureDisp;
136+
aiString textureRoughness;
137+
aiString textureMetallic;
138+
aiString textureSheen;
139+
aiString textureRMA;
136140

137141
enum TextureType {
138142
TextureDiffuseType = 0,
@@ -151,6 +155,10 @@ struct Material {
151155
TextureSpecularityType,
152156
TextureOpacityType,
153157
TextureDispType,
158+
TextureRoughnessType,
159+
TextureMetallicType,
160+
TextureSheenType,
161+
TextureRMAType,
154162
TextureTypeCount
155163
};
156164
bool clamp[TextureTypeCount];
@@ -174,14 +182,33 @@ struct Material {
174182
//! Transparency color
175183
aiColor3D transparent;
176184

185+
//! PBR Roughness
186+
ai_real roughness;
187+
//! PBR Metallic
188+
ai_real metallic;
189+
//! PBR Metallic
190+
aiColor3D sheen;
191+
//! PBR Clearcoat Thickness
192+
ai_real clearcoat_thickness;
193+
//! PBR Clearcoat Rougness
194+
ai_real clearcoat_roughness;
195+
//! PBR Anisotropy
196+
ai_real anisotropy;
197+
177198
//! Constructor
178199
Material() :
179200
diffuse(ai_real(0.6), ai_real(0.6), ai_real(0.6)),
180201
alpha(ai_real(1.0)),
181202
shineness(ai_real(0.0)),
182203
illumination_model(1),
183204
ior(ai_real(1.0)),
184-
transparent(ai_real(1.0), ai_real(1.0), ai_real(1.0)) {
205+
transparent(ai_real(1.0), ai_real(1.0), ai_real(1.0)),
206+
roughness(ai_real(1.0)),
207+
metallic(ai_real(0.0)),
208+
sheen(ai_real(1.0), ai_real(1.0), ai_real(1.0)),
209+
clearcoat_thickness(ai_real(0.0)),
210+
clearcoat_roughness(ai_real(0.0)),
211+
anisotropy(ai_real(0.0)) {
185212
std::fill_n(clamp, static_cast<unsigned int>(TextureTypeCount), false);
186213
}
187214

code/AssetLib/Obj/ObjFileImporter.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,12 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
618618
mat->AddProperty(&pCurrentMaterial->shineness, 1, AI_MATKEY_SHININESS);
619619
mat->AddProperty(&pCurrentMaterial->alpha, 1, AI_MATKEY_OPACITY);
620620
mat->AddProperty(&pCurrentMaterial->transparent, 1, AI_MATKEY_COLOR_TRANSPARENT);
621+
mat->AddProperty(&pCurrentMaterial->roughness, 1, AI_MATKEY_ROUGHNESS_FACTOR);
622+
mat->AddProperty(&pCurrentMaterial->metallic, 1, AI_MATKEY_METALLIC_FACTOR);
623+
mat->AddProperty(&pCurrentMaterial->sheen, 1, AI_MATKEY_SHEEN_COLOR_FACTOR);
624+
mat->AddProperty(&pCurrentMaterial->clearcoat_thickness, 1, AI_MATKEY_CLEARCOAT_FACTOR);
625+
mat->AddProperty(&pCurrentMaterial->clearcoat_roughness, 1, AI_MATKEY_CLEARCOAT_ROUGHNESS_FACTOR);
626+
mat->AddProperty(&pCurrentMaterial->anisotropy, 1, AI_MATKEY_ANISOTROPY_FACTOR);
621627

622628
// Adding refraction index
623629
mat->AddProperty(&pCurrentMaterial->ior, 1, AI_MATKEY_REFRACTI);
@@ -709,6 +715,39 @@ void ObjFileImporter::createMaterials(const ObjFile::Model *pModel, aiScene *pSc
709715
}
710716
}
711717

718+
if (0 != pCurrentMaterial->textureRoughness.length) {
719+
mat->AddProperty(&pCurrentMaterial->textureRoughness, _AI_MATKEY_TEXTURE_BASE, aiTextureType_DIFFUSE_ROUGHNESS, 0);
720+
mat->AddProperty(&uvwIndex, 1, _AI_MATKEY_UVWSRC_BASE, aiTextureType_DIFFUSE_ROUGHNESS, 0 );
721+
if (pCurrentMaterial->clamp[ObjFile::Material::TextureRoughnessType]) {
722+
addTextureMappingModeProperty(mat, aiTextureType_DIFFUSE_ROUGHNESS);
723+
}
724+
}
725+
726+
if (0 != pCurrentMaterial->textureMetallic.length) {
727+
mat->AddProperty(&pCurrentMaterial->textureMetallic, _AI_MATKEY_TEXTURE_BASE, aiTextureType_METALNESS, 0);
728+
mat->AddProperty(&uvwIndex, 1, _AI_MATKEY_UVWSRC_BASE, aiTextureType_METALNESS, 0 );
729+
if (pCurrentMaterial->clamp[ObjFile::Material::TextureMetallicType]) {
730+
addTextureMappingModeProperty(mat, aiTextureType_METALNESS);
731+
}
732+
}
733+
734+
if (0 != pCurrentMaterial->textureSheen.length) {
735+
mat->AddProperty(&pCurrentMaterial->textureSheen, _AI_MATKEY_TEXTURE_BASE, aiTextureType_SHEEN, 0);
736+
mat->AddProperty(&uvwIndex, 1, _AI_MATKEY_UVWSRC_BASE, aiTextureType_SHEEN, 0 );
737+
if (pCurrentMaterial->clamp[ObjFile::Material::TextureSheenType]) {
738+
addTextureMappingModeProperty(mat, aiTextureType_SHEEN);
739+
}
740+
}
741+
742+
if (0 != pCurrentMaterial->textureRMA.length) {
743+
// NOTE: glTF importer places Rough/Metal/AO texture in Unknown so doing the same here for consistency.
744+
mat->AddProperty(&pCurrentMaterial->textureRMA, _AI_MATKEY_TEXTURE_BASE, aiTextureType_UNKNOWN, 0);
745+
mat->AddProperty(&uvwIndex, 1, _AI_MATKEY_UVWSRC_BASE, aiTextureType_UNKNOWN, 0 );
746+
if (pCurrentMaterial->clamp[ObjFile::Material::TextureRMAType]) {
747+
addTextureMappingModeProperty(mat, aiTextureType_UNKNOWN);
748+
}
749+
}
750+
712751
// Store material property info in material array in scene
713752
pScene->mMaterials[pScene->mNumMaterials] = mat;
714753
pScene->mNumMaterials++;

code/AssetLib/Obj/ObjFileMtlImporter.cpp

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ static const std::string ReflectionTexture = "refl";
6767
static const std::string DisplacementTexture1 = "map_disp";
6868
static const std::string DisplacementTexture2 = "disp";
6969
static const std::string SpecularityTexture = "map_ns";
70+
static const std::string RoughnessTexture = "map_Pr";
71+
static const std::string MetallicTexture = "map_Pm";
72+
static const std::string SheenTexture = "map_Ps";
73+
static const std::string RMATexture = "map_Ps";
7074

7175
// texture option specific token
7276
static const std::string BlendUOption = "-blendu";
@@ -178,10 +182,45 @@ void ObjFileMtlImporter::load() {
178182
case 'e': // New material
179183
createMaterial();
180184
break;
185+
case 'o': // Norm texture
186+
--m_DataIt;
187+
getTexture();
188+
break;
181189
}
182190
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
183191
} break;
184192

193+
case 'P':
194+
{
195+
++m_DataIt;
196+
switch(*m_DataIt)
197+
{
198+
case 'r':
199+
++m_DataIt;
200+
getFloatValue(m_pModel->m_pCurrentMaterial->roughness);
201+
break;
202+
case 'm':
203+
++m_DataIt;
204+
getFloatValue(m_pModel->m_pCurrentMaterial->metallic);
205+
break;
206+
case 's':
207+
++m_DataIt;
208+
getColorRGBA(&m_pModel->m_pCurrentMaterial->sheen);
209+
break;
210+
case 'c':
211+
++m_DataIt;
212+
if (*m_DataIt == 'r') {
213+
++m_DataIt;
214+
getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_roughness);
215+
} else {
216+
getFloatValue(m_pModel->m_pCurrentMaterial->clearcoat_thickness);
217+
}
218+
break;
219+
}
220+
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
221+
}
222+
break;
223+
185224
case 'm': // Texture
186225
case 'b': // quick'n'dirty - for 'bump' sections
187226
case 'r': // quick'n'dirty - for 'refl' sections
@@ -197,6 +236,12 @@ void ObjFileMtlImporter::load() {
197236
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
198237
} break;
199238

239+
case 'a': // Anisotropy
240+
{
241+
getFloatValue(m_pModel->m_pCurrentMaterial->anisotropy);
242+
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
243+
} break;
244+
200245
default: {
201246
m_DataIt = skipLine<DataArrayIt>(m_DataIt, m_DataItEnd, m_uiLine);
202247
} break;
@@ -334,6 +379,22 @@ void ObjFileMtlImporter::getTexture() {
334379
// Specularity scaling (glossiness)
335380
out = &m_pModel->m_pCurrentMaterial->textureSpecularity;
336381
clampIndex = ObjFile::Material::TextureSpecularityType;
382+
} else if ( !ASSIMP_strincmp( pPtr, RoughnessTexture.c_str(), static_cast<unsigned int>(RoughnessTexture.size()))) {
383+
// PBR Roughness texture
384+
out = & m_pModel->m_pCurrentMaterial->textureRoughness;
385+
clampIndex = ObjFile::Material::TextureRoughnessType;
386+
} else if ( !ASSIMP_strincmp( pPtr, MetallicTexture.c_str(), static_cast<unsigned int>(MetallicTexture.size()))) {
387+
// PBR Metallic texture
388+
out = & m_pModel->m_pCurrentMaterial->textureMetallic;
389+
clampIndex = ObjFile::Material::TextureMetallicType;
390+
} else if (!ASSIMP_strincmp( pPtr, SheenTexture.c_str(), static_cast<unsigned int>(SheenTexture.size()))) {
391+
// PBR Sheen (reflectance) texture
392+
out = & m_pModel->m_pCurrentMaterial->textureSheen;
393+
clampIndex = ObjFile::Material::TextureSheenType;
394+
} else if (!ASSIMP_strincmp( pPtr, RMATexture.c_str(), static_cast<unsigned int>(RMATexture.size()))) {
395+
// PBR Rough/Metal/AO texture
396+
out = & m_pModel->m_pCurrentMaterial->textureRMA;
397+
clampIndex = ObjFile::Material::TextureRMAType;
337398
} else {
338399
ASSIMP_LOG_ERROR("OBJ/MTL: Encountered unknown texture type");
339400
return;

include/assimp/material.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -989,6 +989,9 @@ extern "C" {
989989
// Roughness factor. 0.0 = Perfectly Smooth, 1.0 = Completely Rough
990990
#define AI_MATKEY_ROUGHNESS_FACTOR "$mat.roughnessFactor", 0, 0
991991
#define AI_MATKEY_ROUGHNESS_TEXTURE aiTextureType_DIFFUSE_ROUGHNESS, 0
992+
// Anisotropy factor. 0.0 = isotropic, 1.0 = anisotropy along tangent direction,
993+
// -1.0 = anisotropy along bitangent direction
994+
#define AI_MATKEY_ANISOTROPY_FACTOR "$mat.anisotropyFactor", 0, 0
992995

993996
// Specular/Glossiness Workflow
994997
// ---------------------------

0 commit comments

Comments
 (0)