From f7be3048de830c5b3567c23a04c3746079bfcb67 Mon Sep 17 00:00:00 2001 From: Malcolm Tyrrell Date: Tue, 1 Dec 2020 12:05:42 +0000 Subject: [PATCH] New 3ds Max PBR Materials in FBX --- code/AssetLib/FBX/FBXConverter.cpp | 15 +- code/AssetLib/FBX/FBXProperties.cpp | 12 +- test/models/FBX/maxPbrMaterial_metalRough.fbx | 618 ++++++++++++++++++ test/models/FBX/maxPbrMaterial_specGloss.fbx | 618 ++++++++++++++++++ test/unit/utFBXImporterExporter.cpp | 106 +++ 5 files changed, 1367 insertions(+), 2 deletions(-) create mode 100644 test/models/FBX/maxPbrMaterial_metalRough.fbx create mode 100644 test/models/FBX/maxPbrMaterial_specGloss.fbx diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index efecf450f..e6b1a75c0 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -2011,12 +2011,25 @@ void FBXConverter::SetTextureProperties(aiMaterial *out_mat, const TextureMap &_ TrySetTextureProperties(out_mat, _textures, "Maya|TEX_roughness_map", aiTextureType_DIFFUSE_ROUGHNESS, mesh); TrySetTextureProperties(out_mat, _textures, "Maya|TEX_ao_map", aiTextureType_AMBIENT_OCCLUSION, mesh); - // 3DSMax PBR + // 3DSMax Physical material TrySetTextureProperties(out_mat, _textures, "3dsMax|Parameters|base_color_map", aiTextureType_BASE_COLOR, mesh); TrySetTextureProperties(out_mat, _textures, "3dsMax|Parameters|bump_map", aiTextureType_NORMAL_CAMERA, mesh); TrySetTextureProperties(out_mat, _textures, "3dsMax|Parameters|emission_map", aiTextureType_EMISSION_COLOR, mesh); TrySetTextureProperties(out_mat, _textures, "3dsMax|Parameters|metalness_map", aiTextureType_METALNESS, mesh); TrySetTextureProperties(out_mat, _textures, "3dsMax|Parameters|roughness_map", aiTextureType_DIFFUSE_ROUGHNESS, mesh); + + // 3DSMax PBR materials + TrySetTextureProperties(out_mat, _textures, "3dsMax|main|base_color_map", aiTextureType_BASE_COLOR, mesh); + TrySetTextureProperties(out_mat, _textures, "3dsMax|main|norm_map", aiTextureType_NORMAL_CAMERA, mesh); + TrySetTextureProperties(out_mat, _textures, "3dsMax|main|emit_color_map", aiTextureType_EMISSION_COLOR, mesh); + TrySetTextureProperties(out_mat, _textures, "3dsMax|main|ao_map", aiTextureType_AMBIENT_OCCLUSION, mesh); + TrySetTextureProperties(out_mat, _textures, "3dsMax|main|opacity_map", aiTextureType_OPACITY, mesh); + // Metalness/Roughness mode + TrySetTextureProperties(out_mat, _textures, "3dsMax|main|metalness_map", aiTextureType_METALNESS, mesh); + TrySetTextureProperties(out_mat, _textures, "3dsMax|main|roughness_map", aiTextureType_DIFFUSE_ROUGHNESS, mesh); + // Specular/Gloss mode + TrySetTextureProperties(out_mat, _textures, "3dsMax|main|specular_map", aiTextureType_SPECULAR, mesh); + TrySetTextureProperties(out_mat, _textures, "3dsMax|main|glossiness_map", aiTextureType_SHININESS, mesh); } void FBXConverter::SetTextureProperties(aiMaterial *out_mat, const LayeredTextureMap &layeredTextures, const MeshGeometry *const mesh) { diff --git a/code/AssetLib/FBX/FBXProperties.cpp b/code/AssetLib/FBX/FBXProperties.cpp index a3a95228e..ccccd3012 100644 --- a/code/AssetLib/FBX/FBXProperties.cpp +++ b/code/AssetLib/FBX/FBXProperties.cpp @@ -90,7 +90,7 @@ Property* ReadTypedProperty(const Element& element) ai_assert(tok.size() >= 5); return new TypedProperty(ParseTokenAsInt(*tok[4]) != 0); } - else if (!strcmp(cs, "int") || !strcmp(cs, "Int") || !strcmp(cs, "enum") || !strcmp(cs, "Enum")) { + else if (!strcmp(cs, "int") || !strcmp(cs, "Int") || !strcmp(cs, "enum") || !strcmp(cs, "Enum") || !strcmp(cs, "Integer")) { ai_assert(tok.size() >= 5); return new TypedProperty(ParseTokenAsInt(*tok[4])); } @@ -121,6 +121,16 @@ Property* ReadTypedProperty(const Element& element) ai_assert(tok.size() >= 5); return new TypedProperty(ParseTokenAsFloat(*tok[4])); } + else if (!strcmp(cs, "ColorAndAlpha")) + { + ai_assert(tok.size() >= 8); + return new TypedProperty(aiColor4D( + ParseTokenAsFloat(*tok[4]), + ParseTokenAsFloat(*tok[5]), + ParseTokenAsFloat(*tok[6]), + ParseTokenAsFloat(*tok[7])) + ); + } return nullptr; } diff --git a/test/models/FBX/maxPbrMaterial_metalRough.fbx b/test/models/FBX/maxPbrMaterial_metalRough.fbx new file mode 100644 index 000000000..a66275269 --- /dev/null +++ b/test/models/FBX/maxPbrMaterial_metalRough.fbx @@ -0,0 +1,618 @@ +; FBX 7.7.0 project file +; ---------------------------------------------------- + +FBXHeaderExtension: { + FBXHeaderVersion: 1004 + FBXVersion: 7700 + CreationTimeStamp: { + Version: 1000 + Year: 2020 + Month: 12 + Day: 1 + Hour: 9 + Minute: 35 + Second: 57 + Millisecond: 532 + } + Creator: "FBX SDK/FBX Plugins version 2020.0.1" + OtherFlags: { + TCDefinition: 127 + } + SceneInfo: "SceneInfo::GlobalInfo", "UserData" { + Type: "UserData" + Version: 100 + MetaData: { + Version: 100 + Title: "" + Subject: "" + Author: "" + Keywords: "" + Revision: "" + Comment: "" + } + Properties70: { + P: "DocumentUrl", "KString", "Url", "", "G:\Temp\Max2021PbrMaterials\MaxPbrMaterial.fbx" + P: "SrcDocumentUrl", "KString", "Url", "", "G:\Temp\Max2021PbrMaterials\MaxPbrMaterial.fbx" + P: "Original", "Compound", "", "" + P: "Original|ApplicationVendor", "KString", "", "", "Autodesk" + P: "Original|ApplicationName", "KString", "", "", "3ds Max" + P: "Original|ApplicationVersion", "KString", "", "", "2021" + P: "Original|DateTime_GMT", "DateTime", "", "", "01/12/2020 09:35:57.532" + P: "Original|FileName", "KString", "", "", "G:\Temp\Max2021PbrMaterials\MaxPbrMaterial.fbx" + P: "LastSaved", "Compound", "", "" + P: "LastSaved|ApplicationVendor", "KString", "", "", "Autodesk" + P: "LastSaved|ApplicationName", "KString", "", "", "3ds Max" + P: "LastSaved|ApplicationVersion", "KString", "", "", "2021" + P: "LastSaved|DateTime_GMT", "DateTime", "", "", "01/12/2020 09:35:57.532" + P: "Original|ApplicationActiveProject", "KString", "", "", "C:\3ds Max 2021" + P: "Original|ApplicationNativeFile", "KString", "", "", "C;\3ds Max 2021\MaxPbrMaterial.max" + } + } +} +GlobalSettings: { + Version: 1000 + Properties70: { + P: "UpAxis", "int", "Integer", "",1 + P: "UpAxisSign", "int", "Integer", "",1 + P: "FrontAxis", "int", "Integer", "",2 + P: "FrontAxisSign", "int", "Integer", "",1 + P: "CoordAxis", "int", "Integer", "",0 + P: "CoordAxisSign", "int", "Integer", "",1 + P: "OriginalUpAxis", "int", "Integer", "",2 + P: "OriginalUpAxisSign", "int", "Integer", "",1 + P: "UnitScaleFactor", "double", "Number", "",100 + P: "OriginalUnitScaleFactor", "double", "Number", "",100.00000066 + P: "AmbientColor", "ColorRGB", "Color", "",0,0,0 + P: "DefaultCamera", "KString", "", "", "Producer Perspective" + P: "TimeMode", "enum", "", "",6 + P: "TimeProtocol", "enum", "", "",2 + P: "SnapOnFrameMode", "enum", "", "",0 + P: "TimeSpanStart", "KTime", "Time", "",0 + P: "TimeSpanStop", "KTime", "Time", "",153953860000 + P: "CustomFrameRate", "double", "Number", "",-1 + P: "TimeMarker", "Compound", "", "" + P: "CurrentTimeMarker", "int", "Integer", "",-1 + } +} + +; Documents Description +;------------------------------------------------------------------ + +Documents: { + Count: 1 + Document: 2188301813872, "", "Scene" { + Properties70: { + P: "SourceObject", "object", "", "" + P: "ActiveAnimStackName", "KString", "", "", "" + } + RootNode: 0 + } +} + +; Document References +;------------------------------------------------------------------ + +References: { +} + +; Object definitions +;------------------------------------------------------------------ + +Definitions: { + Version: 100 + Count: 18 + ObjectType: "GlobalSettings" { + Count: 1 + } + ObjectType: "Model" { + Count: 1 + PropertyTemplate: "FbxNode" { + Properties70: { + P: "QuaternionInterpolate", "enum", "", "",0 + P: "RotationOffset", "Vector3D", "Vector", "",0,0,0 + P: "RotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "ScalingOffset", "Vector3D", "Vector", "",0,0,0 + P: "ScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "TranslationActive", "bool", "", "",0 + P: "TranslationMin", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMax", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMinX", "bool", "", "",0 + P: "TranslationMinY", "bool", "", "",0 + P: "TranslationMinZ", "bool", "", "",0 + P: "TranslationMaxX", "bool", "", "",0 + P: "TranslationMaxY", "bool", "", "",0 + P: "TranslationMaxZ", "bool", "", "",0 + P: "RotationOrder", "enum", "", "",0 + P: "RotationSpaceForLimitOnly", "bool", "", "",0 + P: "RotationStiffnessX", "double", "Number", "",0 + P: "RotationStiffnessY", "double", "Number", "",0 + P: "RotationStiffnessZ", "double", "Number", "",0 + P: "AxisLen", "double", "Number", "",10 + P: "PreRotation", "Vector3D", "Vector", "",0,0,0 + P: "PostRotation", "Vector3D", "Vector", "",0,0,0 + P: "RotationActive", "bool", "", "",0 + P: "RotationMin", "Vector3D", "Vector", "",0,0,0 + P: "RotationMax", "Vector3D", "Vector", "",0,0,0 + P: "RotationMinX", "bool", "", "",0 + P: "RotationMinY", "bool", "", "",0 + P: "RotationMinZ", "bool", "", "",0 + P: "RotationMaxX", "bool", "", "",0 + P: "RotationMaxY", "bool", "", "",0 + P: "RotationMaxZ", "bool", "", "",0 + P: "InheritType", "enum", "", "",0 + P: "ScalingActive", "bool", "", "",0 + P: "ScalingMin", "Vector3D", "Vector", "",0,0,0 + P: "ScalingMax", "Vector3D", "Vector", "",1,1,1 + P: "ScalingMinX", "bool", "", "",0 + P: "ScalingMinY", "bool", "", "",0 + P: "ScalingMinZ", "bool", "", "",0 + P: "ScalingMaxX", "bool", "", "",0 + P: "ScalingMaxY", "bool", "", "",0 + P: "ScalingMaxZ", "bool", "", "",0 + P: "GeometricTranslation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricRotation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricScaling", "Vector3D", "Vector", "",1,1,1 + P: "MinDampRangeX", "double", "Number", "",0 + P: "MinDampRangeY", "double", "Number", "",0 + P: "MinDampRangeZ", "double", "Number", "",0 + P: "MaxDampRangeX", "double", "Number", "",0 + P: "MaxDampRangeY", "double", "Number", "",0 + P: "MaxDampRangeZ", "double", "Number", "",0 + P: "MinDampStrengthX", "double", "Number", "",0 + P: "MinDampStrengthY", "double", "Number", "",0 + P: "MinDampStrengthZ", "double", "Number", "",0 + P: "MaxDampStrengthX", "double", "Number", "",0 + P: "MaxDampStrengthY", "double", "Number", "",0 + P: "MaxDampStrengthZ", "double", "Number", "",0 + P: "PreferedAngleX", "double", "Number", "",0 + P: "PreferedAngleY", "double", "Number", "",0 + P: "PreferedAngleZ", "double", "Number", "",0 + P: "LookAtProperty", "object", "", "" + P: "UpVectorProperty", "object", "", "" + P: "Show", "bool", "", "",1 + P: "NegativePercentShapeSupport", "bool", "", "",1 + P: "DefaultAttributeIndex", "int", "Integer", "",-1 + P: "Freeze", "bool", "", "",0 + P: "LODBox", "bool", "", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0,0,0 + P: "Lcl Rotation", "Lcl Rotation", "", "A",0,0,0 + P: "Lcl Scaling", "Lcl Scaling", "", "A",1,1,1 + P: "Visibility", "Visibility", "", "A",1 + P: "Visibility Inheritance", "Visibility Inheritance", "", "",1 + } + } + } + ObjectType: "Geometry" { + Count: 1 + PropertyTemplate: "FbxMesh" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "BBoxMin", "Vector3D", "Vector", "",0,0,0 + P: "BBoxMax", "Vector3D", "Vector", "",0,0,0 + P: "Primary Visibility", "bool", "", "",1 + P: "Casts Shadows", "bool", "", "",1 + P: "Receive Shadows", "bool", "", "",1 + } + } + } + ObjectType: "Material" { + Count: 1 + PropertyTemplate: "FbxSurfaceMaterial" { + Properties70: { + P: "ShadingModel", "KString", "", "", "Unknown" + P: "MultiLayer", "bool", "", "",0 + } + } + } + ObjectType: "Texture" { + Count: 7 + PropertyTemplate: "FbxFileTexture" { + Properties70: { + P: "TextureTypeUse", "enum", "", "",0 + P: "Texture alpha", "Number", "", "A",1 + P: "CurrentMappingType", "enum", "", "",0 + P: "WrapModeU", "enum", "", "",0 + P: "WrapModeV", "enum", "", "",0 + P: "UVSwap", "bool", "", "",0 + P: "PremultiplyAlpha", "bool", "", "",1 + P: "Translation", "Vector", "", "A",0,0,0 + P: "Rotation", "Vector", "", "A",0,0,0 + P: "Scaling", "Vector", "", "A",1,1,1 + P: "TextureRotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "TextureScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "CurrentTextureBlendMode", "enum", "", "",1 + P: "UVSet", "KString", "", "", "default" + P: "UseMaterial", "bool", "", "",0 + P: "UseMipMap", "bool", "", "",0 + } + } + } + ObjectType: "Video" { + Count: 7 + PropertyTemplate: "FbxVideo" { + Properties70: { + P: "Path", "KString", "XRefUrl", "", "" + P: "RelPath", "KString", "XRefUrl", "", "" + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "ClipIn", "KTime", "Time", "",0 + P: "ClipOut", "KTime", "Time", "",0 + P: "Offset", "KTime", "Time", "",0 + P: "PlaySpeed", "double", "Number", "",0 + P: "FreeRunning", "bool", "", "",0 + P: "Loop", "bool", "", "",0 + P: "Mute", "bool", "", "",0 + P: "AccessMode", "enum", "", "",0 + P: "ImageSequence", "bool", "", "",0 + P: "ImageSequenceOffset", "int", "Integer", "",0 + P: "FrameRate", "double", "Number", "",0 + P: "LastFrame", "int", "Integer", "",0 + P: "Width", "int", "Integer", "",0 + P: "Height", "int", "Integer", "",0 + P: "StartFrame", "int", "Integer", "",0 + P: "StopFrame", "int", "Integer", "",0 + P: "InterlaceMode", "enum", "", "",0 + } + } + } +} + +; Object properties +;------------------------------------------------------------------ + +Objects: { + Geometry: 2188426094640, "Geometry::", "Mesh" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.341176470588235,0.882352941176471,0.776470588235294 + } + Vertices: *24 { + a: -8.91135215759277,-10.98219871521,0,8.91135215759277,-10.98219871521,0,-8.91135215759277,10.98219871521,0,8.91135215759277,10.98219871521,0,-8.91135215759277,-10.98219871521,16.787576675415,8.91135215759277,-10.98219871521,16.787576675415,-8.91135215759277,10.98219871521,16.787576675415,8.91135215759277,10.98219871521,16.787576675415 + } + PolygonVertexIndex: *24 { + a: 0,2,3,-2,4,5,7,-7,0,1,5,-5,1,3,7,-6,3,2,6,-8,2,0,4,-7 + } + Edges: *12 { + a: 0,1,2,3,4,5,6,7,9,11,13,17 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Normals: *72 { + a: 0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0 + } + NormalsW: *24 { + a: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "UVChannel_1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *48 { + a: 1,0,0,0,1,1,0,1,0,0,1,0,0,1,1,1,0,0,1,0,0,1,1,1,0,0,1,0,0,1,1,1,0,0,1,0,0,1,1,1,0,0,1,0,0,1,1,1 + } + UVIndex: *24 { + a: 0,2,3,1,4,5,7,6,8,9,11,10,12,13,15,14,16,17,19,18,20,21,23,22 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "AllSame" + ReferenceInformationType: "IndexToDirect" + Materials: *1 { + a: 0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Model: 2187845653184, "Model::Box001", "Mesh" { + Version: 232 + Properties70: { + P: "PreRotation", "Vector3D", "Vector", "",-90,-0,0 + P: "RotationActive", "bool", "", "",1 + P: "InheritType", "enum", "", "",1 + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0.570660591125488,0,-0.671265125274658 + P: "MaxHandle", "int", "Integer", "UH",2 + } + Shading: T + Culling: "CullingOff" + } + Material: 2188102329504, "Material::PBR Material", "" { + Version: 102 + ShadingModel: "unknown" + MultiLayer: 0 + Properties70: { + P: "ShadingModel", "KString", "", "", "unknown" + P: "AmbientColor", "ColorRGB", "Color", "",0,1,1 + P: "DiffuseColor", "ColorRGB", "Color", "",0,1,1 + P: "SpecularColor", "ColorRGB", "Color", "",0.75,1,1 + P: "SpecularFactor", "double", "Number", "",2.25 + P: "ShininessExponent", "double", "Number", "",32 + P: "TransparencyFactor", "double", "Number", "",0 + P: "EmissiveColor", "ColorRGB", "Color", "",3.14159274101257,3.14159250259399,0 + P: "EmissiveFactor", "double", "Number", "",1 + P: "3dsMax", "Compound", "", "" + P: "3dsMax|ClassIDa", "int", "Integer", "",-804315648 + P: "3dsMax|ClassIDb", "int", "Integer", "",-1099438848 + P: "3dsMax|SuperClassID", "int", "Integer", "",3072 + P: "3dsMax|settings", "Compound", "", "" + P: "3dsMax|settings|ao_affects_diffuse", "Bool", "", "A",1 + P: "3dsMax|settings|ao_affects_reflection", "Bool", "", "A",1 + P: "3dsMax|settings|normal_flip_red", "Bool", "", "A",0 + P: "3dsMax|settings|normal_flip_green", "Bool", "", "A",0 + P: "3dsMax|main", "Compound", "", "" + P: "3dsMax|main|basecolor", "ColorAndAlpha", "", "A",0,1,1,1 + P: "3dsMax|main|base_color_map", "Reference", "", "A" + P: "3dsMax|main|metalness", "Float", "", "A",0.25 + P: "3dsMax|main|metalness_map", "Reference", "", "A" + P: "3dsMax|main|roughness", "Float", "", "A",0.5 + P: "3dsMax|main|roughness_map", "Reference", "", "A" + P: "3dsMax|main|useGlossiness", "Integer", "", "A",2 + P: "3dsMax|main|ao_map", "Reference", "", "A" + P: "3dsMax|main|bump_map_amt", "Float", "", "A",0.75 + P: "3dsMax|main|norm_map", "Reference", "", "A" + P: "3dsMax|main|emit_color", "ColorAndAlpha", "", "A",1,1,0,1 + P: "3dsMax|main|emit_color_map", "Reference", "", "A" + P: "3dsMax|main|opacity_map", "Reference", "", "A" + } + } + Video: 2188262711712, "Video::Albedo", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\albedo.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\albedo.png" + } + UseMipMap: 0 + Filename: "Textures\albedo.png" + RelativeFilename: "Textures\albedo.png" + } + Video: 2188262695872, "Video::Metalness", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\metalness.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\metalness.png" + } + UseMipMap: 0 + Filename: "Textures\metalness.png" + RelativeFilename: "Textures\metalness.png" + } + Video: 2188262686752, "Video::Roughness", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\roughness.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\roughness.png" + } + UseMipMap: 0 + Filename: "Textures\roughness.png" + RelativeFilename: "Textures\roughness.png" + } + Video: 2188262700672, "Video::Occlusion", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\occlusion.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\occlusion.png" + } + UseMipMap: 0 + Filename: "Textures\occlusion.png" + RelativeFilename: "Textures\occlusion.png" + } + Video: 2188262708832, "Video::Normal", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\normal.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\normal.png" + } + UseMipMap: 0 + Filename: "Textures\normal.png" + RelativeFilename: "Textures\normal.png" + } + Video: 2188262712672, "Video::Emission", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\emission.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\emission.png" + } + UseMipMap: 0 + Filename: "Textures\emission.png" + RelativeFilename: "Textures\emission.png" + } + Video: 2188262696352, "Video::Opacity", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\opacity.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\opacity.png" + } + UseMipMap: 0 + Filename: "Textures\opacity.png" + RelativeFilename: "Textures\opacity.png" + } + Texture: 2188262656992, "Texture::Albedo", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Albedo" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Albedo" + FileName: "Textures\albedo.png" + RelativeFilename: "Textures\albedo.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 2188262678592, "Texture::Metalness", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Metalness" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Metalness" + FileName: "Textures\metalness.png" + RelativeFilename: "Textures\metalness.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 2188262682432, "Texture::Roughness", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Roughness" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Roughness" + FileName: "Textures\roughness.png" + RelativeFilename: "Textures\roughness.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 2188262656032, "Texture::Occlusion", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Occlusion" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Occlusion" + FileName: "Textures\occlusion.png" + RelativeFilename: "Textures\occlusion.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 2188262659392, "Texture::Normal", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Normal" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Normal" + FileName: "Textures\normal.png" + RelativeFilename: "Textures\normal.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 2188262700192, "Texture::Emission", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Emission" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Emission" + FileName: "Textures\emission.png" + RelativeFilename: "Textures\emission.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 2188262684832, "Texture::Opacity", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Opacity" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Opacity" + FileName: "Textures\opacity.png" + RelativeFilename: "Textures\opacity.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } +} + +; Object connections +;------------------------------------------------------------------ + +Connections: { + + ;Model::Box001, Model::RootNode + C: "OO",2187845653184,0 + + ;Geometry::, Model::Box001 + C: "OO",2188426094640,2187845653184 + + ;Material::PBR Material, Model::Box001 + C: "OO",2188102329504,2187845653184 + + ;Texture::Albedo, Material::PBR Material + C: "OP",2188262656992,2188102329504, "3dsMax|main|base_color_map" + + ;Texture::Metalness, Material::PBR Material + C: "OP",2188262678592,2188102329504, "3dsMax|main|metalness_map" + + ;Texture::Roughness, Material::PBR Material + C: "OP",2188262682432,2188102329504, "3dsMax|main|roughness_map" + + ;Texture::Occlusion, Material::PBR Material + C: "OP",2188262656032,2188102329504, "3dsMax|main|ao_map" + + ;Texture::Normal, Material::PBR Material + C: "OP",2188262659392,2188102329504, "3dsMax|main|norm_map" + + ;Texture::Emission, Material::PBR Material + C: "OP",2188262700192,2188102329504, "3dsMax|main|emit_color_map" + + ;Texture::Opacity, Material::PBR Material + C: "OP",2188262684832,2188102329504, "3dsMax|main|opacity_map" + + ;Video::Albedo, Texture::Albedo + C: "OO",2188262711712,2188262656992 + + ;Video::Metalness, Texture::Metalness + C: "OO",2188262695872,2188262678592 + + ;Video::Roughness, Texture::Roughness + C: "OO",2188262686752,2188262682432 + + ;Video::Occlusion, Texture::Occlusion + C: "OO",2188262700672,2188262656032 + + ;Video::Normal, Texture::Normal + C: "OO",2188262708832,2188262659392 + + ;Video::Emission, Texture::Emission + C: "OO",2188262712672,2188262700192 + + ;Video::Opacity, Texture::Opacity + C: "OO",2188262696352,2188262684832 +} diff --git a/test/models/FBX/maxPbrMaterial_specGloss.fbx b/test/models/FBX/maxPbrMaterial_specGloss.fbx new file mode 100644 index 000000000..83a4432c9 --- /dev/null +++ b/test/models/FBX/maxPbrMaterial_specGloss.fbx @@ -0,0 +1,618 @@ +; FBX 7.7.0 project file +; ---------------------------------------------------- + +FBXHeaderExtension: { + FBXHeaderVersion: 1004 + FBXVersion: 7700 + CreationTimeStamp: { + Version: 1000 + Year: 2020 + Month: 12 + Day: 1 + Hour: 11 + Minute: 50 + Second: 44 + Millisecond: 89 + } + Creator: "FBX SDK/FBX Plugins version 2020.0.1" + OtherFlags: { + TCDefinition: 127 + } + SceneInfo: "SceneInfo::GlobalInfo", "UserData" { + Type: "UserData" + Version: 100 + MetaData: { + Version: 100 + Title: "" + Subject: "" + Author: "" + Keywords: "" + Revision: "" + Comment: "" + } + Properties70: { + P: "DocumentUrl", "KString", "Url", "", "C:\3ds Max 2021\maxPbrMaterial_specGloss.fbx" + P: "SrcDocumentUrl", "KString", "Url", "", "C:\3ds Max 2021\maxPbrMaterial_specGloss.fbx" + P: "Original", "Compound", "", "" + P: "Original|ApplicationVendor", "KString", "", "", "Autodesk" + P: "Original|ApplicationName", "KString", "", "", "3ds Max" + P: "Original|ApplicationVersion", "KString", "", "", "2021" + P: "Original|DateTime_GMT", "DateTime", "", "", "01/12/2020 11:50:44.088" + P: "Original|FileName", "KString", "", "", "C:\3ds Max 2021\maxPbrMaterial_specGloss.fbx" + P: "LastSaved", "Compound", "", "" + P: "LastSaved|ApplicationVendor", "KString", "", "", "Autodesk" + P: "LastSaved|ApplicationName", "KString", "", "", "3ds Max" + P: "LastSaved|ApplicationVersion", "KString", "", "", "2021" + P: "LastSaved|DateTime_GMT", "DateTime", "", "", "01/12/2020 11:50:44.088" + P: "Original|ApplicationActiveProject", "KString", "", "", "C:\3ds Max 2021" + P: "Original|ApplicationNativeFile", "KString", "", "", "C:\3ds Max 2021\MaxPbrMaterial2.max" + } + } +} +GlobalSettings: { + Version: 1000 + Properties70: { + P: "UpAxis", "int", "Integer", "",1 + P: "UpAxisSign", "int", "Integer", "",1 + P: "FrontAxis", "int", "Integer", "",2 + P: "FrontAxisSign", "int", "Integer", "",1 + P: "CoordAxis", "int", "Integer", "",0 + P: "CoordAxisSign", "int", "Integer", "",1 + P: "OriginalUpAxis", "int", "Integer", "",2 + P: "OriginalUpAxisSign", "int", "Integer", "",1 + P: "UnitScaleFactor", "double", "Number", "",100 + P: "OriginalUnitScaleFactor", "double", "Number", "",100.00000066 + P: "AmbientColor", "ColorRGB", "Color", "",0,0,0 + P: "DefaultCamera", "KString", "", "", "Producer Perspective" + P: "TimeMode", "enum", "", "",6 + P: "TimeProtocol", "enum", "", "",2 + P: "SnapOnFrameMode", "enum", "", "",0 + P: "TimeSpanStart", "KTime", "Time", "",0 + P: "TimeSpanStop", "KTime", "Time", "",153953860000 + P: "CustomFrameRate", "double", "Number", "",-1 + P: "TimeMarker", "Compound", "", "" + P: "CurrentTimeMarker", "int", "Integer", "",-1 + } +} + +; Documents Description +;------------------------------------------------------------------ + +Documents: { + Count: 1 + Document: 2188636931248, "", "Scene" { + Properties70: { + P: "SourceObject", "object", "", "" + P: "ActiveAnimStackName", "KString", "", "", "" + } + RootNode: 0 + } +} + +; Document References +;------------------------------------------------------------------ + +References: { +} + +; Object definitions +;------------------------------------------------------------------ + +Definitions: { + Version: 100 + Count: 18 + ObjectType: "GlobalSettings" { + Count: 1 + } + ObjectType: "Model" { + Count: 1 + PropertyTemplate: "FbxNode" { + Properties70: { + P: "QuaternionInterpolate", "enum", "", "",0 + P: "RotationOffset", "Vector3D", "Vector", "",0,0,0 + P: "RotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "ScalingOffset", "Vector3D", "Vector", "",0,0,0 + P: "ScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "TranslationActive", "bool", "", "",0 + P: "TranslationMin", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMax", "Vector3D", "Vector", "",0,0,0 + P: "TranslationMinX", "bool", "", "",0 + P: "TranslationMinY", "bool", "", "",0 + P: "TranslationMinZ", "bool", "", "",0 + P: "TranslationMaxX", "bool", "", "",0 + P: "TranslationMaxY", "bool", "", "",0 + P: "TranslationMaxZ", "bool", "", "",0 + P: "RotationOrder", "enum", "", "",0 + P: "RotationSpaceForLimitOnly", "bool", "", "",0 + P: "RotationStiffnessX", "double", "Number", "",0 + P: "RotationStiffnessY", "double", "Number", "",0 + P: "RotationStiffnessZ", "double", "Number", "",0 + P: "AxisLen", "double", "Number", "",10 + P: "PreRotation", "Vector3D", "Vector", "",0,0,0 + P: "PostRotation", "Vector3D", "Vector", "",0,0,0 + P: "RotationActive", "bool", "", "",0 + P: "RotationMin", "Vector3D", "Vector", "",0,0,0 + P: "RotationMax", "Vector3D", "Vector", "",0,0,0 + P: "RotationMinX", "bool", "", "",0 + P: "RotationMinY", "bool", "", "",0 + P: "RotationMinZ", "bool", "", "",0 + P: "RotationMaxX", "bool", "", "",0 + P: "RotationMaxY", "bool", "", "",0 + P: "RotationMaxZ", "bool", "", "",0 + P: "InheritType", "enum", "", "",0 + P: "ScalingActive", "bool", "", "",0 + P: "ScalingMin", "Vector3D", "Vector", "",0,0,0 + P: "ScalingMax", "Vector3D", "Vector", "",1,1,1 + P: "ScalingMinX", "bool", "", "",0 + P: "ScalingMinY", "bool", "", "",0 + P: "ScalingMinZ", "bool", "", "",0 + P: "ScalingMaxX", "bool", "", "",0 + P: "ScalingMaxY", "bool", "", "",0 + P: "ScalingMaxZ", "bool", "", "",0 + P: "GeometricTranslation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricRotation", "Vector3D", "Vector", "",0,0,0 + P: "GeometricScaling", "Vector3D", "Vector", "",1,1,1 + P: "MinDampRangeX", "double", "Number", "",0 + P: "MinDampRangeY", "double", "Number", "",0 + P: "MinDampRangeZ", "double", "Number", "",0 + P: "MaxDampRangeX", "double", "Number", "",0 + P: "MaxDampRangeY", "double", "Number", "",0 + P: "MaxDampRangeZ", "double", "Number", "",0 + P: "MinDampStrengthX", "double", "Number", "",0 + P: "MinDampStrengthY", "double", "Number", "",0 + P: "MinDampStrengthZ", "double", "Number", "",0 + P: "MaxDampStrengthX", "double", "Number", "",0 + P: "MaxDampStrengthY", "double", "Number", "",0 + P: "MaxDampStrengthZ", "double", "Number", "",0 + P: "PreferedAngleX", "double", "Number", "",0 + P: "PreferedAngleY", "double", "Number", "",0 + P: "PreferedAngleZ", "double", "Number", "",0 + P: "LookAtProperty", "object", "", "" + P: "UpVectorProperty", "object", "", "" + P: "Show", "bool", "", "",1 + P: "NegativePercentShapeSupport", "bool", "", "",1 + P: "DefaultAttributeIndex", "int", "Integer", "",-1 + P: "Freeze", "bool", "", "",0 + P: "LODBox", "bool", "", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0,0,0 + P: "Lcl Rotation", "Lcl Rotation", "", "A",0,0,0 + P: "Lcl Scaling", "Lcl Scaling", "", "A",1,1,1 + P: "Visibility", "Visibility", "", "A",1 + P: "Visibility Inheritance", "Visibility Inheritance", "", "",1 + } + } + } + ObjectType: "Geometry" { + Count: 1 + PropertyTemplate: "FbxMesh" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "BBoxMin", "Vector3D", "Vector", "",0,0,0 + P: "BBoxMax", "Vector3D", "Vector", "",0,0,0 + P: "Primary Visibility", "bool", "", "",1 + P: "Casts Shadows", "bool", "", "",1 + P: "Receive Shadows", "bool", "", "",1 + } + } + } + ObjectType: "Material" { + Count: 1 + PropertyTemplate: "FbxSurfaceMaterial" { + Properties70: { + P: "ShadingModel", "KString", "", "", "Unknown" + P: "MultiLayer", "bool", "", "",0 + } + } + } + ObjectType: "Texture" { + Count: 7 + PropertyTemplate: "FbxFileTexture" { + Properties70: { + P: "TextureTypeUse", "enum", "", "",0 + P: "Texture alpha", "Number", "", "A",1 + P: "CurrentMappingType", "enum", "", "",0 + P: "WrapModeU", "enum", "", "",0 + P: "WrapModeV", "enum", "", "",0 + P: "UVSwap", "bool", "", "",0 + P: "PremultiplyAlpha", "bool", "", "",1 + P: "Translation", "Vector", "", "A",0,0,0 + P: "Rotation", "Vector", "", "A",0,0,0 + P: "Scaling", "Vector", "", "A",1,1,1 + P: "TextureRotationPivot", "Vector3D", "Vector", "",0,0,0 + P: "TextureScalingPivot", "Vector3D", "Vector", "",0,0,0 + P: "CurrentTextureBlendMode", "enum", "", "",1 + P: "UVSet", "KString", "", "", "default" + P: "UseMaterial", "bool", "", "",0 + P: "UseMipMap", "bool", "", "",0 + } + } + } + ObjectType: "Video" { + Count: 7 + PropertyTemplate: "FbxVideo" { + Properties70: { + P: "Path", "KString", "XRefUrl", "", "" + P: "RelPath", "KString", "XRefUrl", "", "" + P: "Color", "ColorRGB", "Color", "",0.8,0.8,0.8 + P: "ClipIn", "KTime", "Time", "",0 + P: "ClipOut", "KTime", "Time", "",0 + P: "Offset", "KTime", "Time", "",0 + P: "PlaySpeed", "double", "Number", "",0 + P: "FreeRunning", "bool", "", "",0 + P: "Loop", "bool", "", "",0 + P: "Mute", "bool", "", "",0 + P: "AccessMode", "enum", "", "",0 + P: "ImageSequence", "bool", "", "",0 + P: "ImageSequenceOffset", "int", "Integer", "",0 + P: "FrameRate", "double", "Number", "",0 + P: "LastFrame", "int", "Integer", "",0 + P: "Width", "int", "Integer", "",0 + P: "Height", "int", "Integer", "",0 + P: "StartFrame", "int", "Integer", "",0 + P: "StopFrame", "int", "Integer", "",0 + P: "InterlaceMode", "enum", "", "",0 + } + } + } +} + +; Object properties +;------------------------------------------------------------------ + +Objects: { + Geometry: 2188631051296, "Geometry::", "Mesh" { + Properties70: { + P: "Color", "ColorRGB", "Color", "",0.341176470588235,0.882352941176471,0.776470588235294 + } + Vertices: *24 { + a: -8.91135215759277,-10.98219871521,0,8.91135215759277,-10.98219871521,0,-8.91135215759277,10.98219871521,0,8.91135215759277,10.98219871521,0,-8.91135215759277,-10.98219871521,16.787576675415,8.91135215759277,-10.98219871521,16.787576675415,-8.91135215759277,10.98219871521,16.787576675415,8.91135215759277,10.98219871521,16.787576675415 + } + PolygonVertexIndex: *24 { + a: 0,2,3,-2,4,5,7,-7,0,1,5,-5,1,3,7,-6,3,2,6,-8,2,0,4,-7 + } + Edges: *12 { + a: 0,1,2,3,4,5,6,7,9,11,13,17 + } + GeometryVersion: 124 + LayerElementNormal: 0 { + Version: 102 + Name: "" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "Direct" + Normals: *72 { + a: 0,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,1,0,0,1,0,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,0,0,1,0,-1,0,0,-1,0,0,-1,0,0,-1,0,0 + } + NormalsW: *24 { + a: 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + } + } + LayerElementUV: 0 { + Version: 101 + Name: "UVChannel_1" + MappingInformationType: "ByPolygonVertex" + ReferenceInformationType: "IndexToDirect" + UV: *48 { + a: 1,0,0,0,1,1,0,1,0,0,1,0,0,1,1,1,0,0,1,0,0,1,1,1,0,0,1,0,0,1,1,1,0,0,1,0,0,1,1,1,0,0,1,0,0,1,1,1 + } + UVIndex: *24 { + a: 0,2,3,1,4,5,7,6,8,9,11,10,12,13,15,14,16,17,19,18,20,21,23,22 + } + } + LayerElementMaterial: 0 { + Version: 101 + Name: "" + MappingInformationType: "AllSame" + ReferenceInformationType: "IndexToDirect" + Materials: *1 { + a: 0 + } + } + Layer: 0 { + Version: 100 + LayerElement: { + Type: "LayerElementNormal" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementMaterial" + TypedIndex: 0 + } + LayerElement: { + Type: "LayerElementUV" + TypedIndex: 0 + } + } + } + Model: 2188763600256, "Model::Box001", "Mesh" { + Version: 232 + Properties70: { + P: "PreRotation", "Vector3D", "Vector", "",-90,-0,0 + P: "RotationActive", "bool", "", "",1 + P: "InheritType", "enum", "", "",1 + P: "ScalingMax", "Vector3D", "Vector", "",0,0,0 + P: "DefaultAttributeIndex", "int", "Integer", "",0 + P: "Lcl Translation", "Lcl Translation", "", "A",0.570660591125488,0,-0.671265125274658 + P: "MaxHandle", "int", "Integer", "UH",2 + } + Shading: T + Culling: "CullingOff" + } + Material: 2188661245104, "Material::02 - Default", "" { + Version: 102 + ShadingModel: "unknown" + MultiLayer: 0 + Properties70: { + P: "ShadingModel", "KString", "", "", "unknown" + P: "AmbientColor", "ColorRGB", "Color", "",0,1,1 + P: "DiffuseColor", "ColorRGB", "Color", "",0,1,1 + P: "SpecularColor", "ColorRGB", "Color", "",1,1,1 + P: "SpecularFactor", "double", "Number", "",2 + P: "ShininessExponent", "double", "Number", "",1024 + P: "TransparencyFactor", "double", "Number", "",0 + P: "EmissiveColor", "ColorRGB", "Color", "",3.14159274101257,0,3.14159321784973 + P: "EmissiveFactor", "double", "Number", "",1 + P: "3dsMax", "Compound", "", "" + P: "3dsMax|ClassIDa", "int", "Integer", "",-804315648 + P: "3dsMax|ClassIDb", "int", "Integer", "",31173939 + P: "3dsMax|SuperClassID", "int", "Integer", "",3072 + P: "3dsMax|settings", "Compound", "", "" + P: "3dsMax|settings|ao_affects_diffuse", "Bool", "", "A",1 + P: "3dsMax|settings|ao_affects_reflection", "Bool", "", "A",1 + P: "3dsMax|settings|normal_flip_red", "Bool", "", "A",0 + P: "3dsMax|settings|normal_flip_green", "Bool", "", "A",0 + P: "3dsMax|main", "Compound", "", "" + P: "3dsMax|main|basecolor", "ColorAndAlpha", "", "A",0,1,1,1 + P: "3dsMax|main|base_color_map", "Reference", "", "A" + P: "3dsMax|main|Specular", "ColorAndAlpha", "", "A",1,1,0,1 + P: "3dsMax|main|specular_map", "Reference", "", "A" + P: "3dsMax|main|glossiness", "Float", "", "A",0.33 + P: "3dsMax|main|glossiness_map", "Reference", "", "A" + P: "3dsMax|main|useGlossiness", "Integer", "", "A",1 + P: "3dsMax|main|ao_map", "Reference", "", "A" + P: "3dsMax|main|bump_map_amt", "Float", "", "A",0.66 + P: "3dsMax|main|norm_map", "Reference", "", "A" + P: "3dsMax|main|emit_color", "ColorAndAlpha", "", "A",1,0,1,1 + P: "3dsMax|main|emit_color_map", "Reference", "", "A" + P: "3dsMax|main|opacity_map", "Reference", "", "A" + } + } + Video: 2188262470272, "Video::Albedo", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\albedo.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\albedo.png" + } + UseMipMap: 0 + Filename: "Textures\albedo.png" + RelativeFilename: "Textures\albedo.png" + } + Video: 2188262470752, "Video::Specular", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\specular.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\specular.png" + } + UseMipMap: 0 + Filename: "Textures\specular.png" + RelativeFilename: "Textures\specular.png" + } + Video: 2188262476032, "Video::Glossiness", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\glossiness.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\glossiness.png" + } + UseMipMap: 0 + Filename: "Textures\glossiness.png" + RelativeFilename: "Textures\glossiness.png" + } + Video: 2188262483232, "Video::Occlusion", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\occlusion.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\occlusion.png" + } + UseMipMap: 0 + Filename: "Textures\occlusion.png" + RelativeFilename: "Textures\occlusion.png" + } + Video: 2188262486112, "Video::Normal", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\normal.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\normal.png" + } + UseMipMap: 0 + Filename: "Textures\normal.png" + RelativeFilename: "Textures\normal.png" + } + Video: 2188262486592, "Video::Emission", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\emission.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\emission.png" + } + UseMipMap: 0 + Filename: "Textures\emission.png" + RelativeFilename: "Textures\emission.png" + } + Video: 2188262687712, "Video::Opacity", "Clip" { + Type: "Clip" + Properties70: { + P: "Path", "KString", "XRefUrl", "", "Textures\opacity.png" + P: "RelPath", "KString", "XRefUrl", "", "Textures\opacity.png" + } + UseMipMap: 0 + Filename: "Textures\opacity.png" + RelativeFilename: "Textures\opacity.png" + } + Texture: 2188262484672, "Texture::Albedo", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Albedo" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Albedo" + FileName: "Textures\albedo.png" + RelativeFilename: "Textures\albedo.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 2188262499552, "Texture::Specular", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Specular" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Specular" + FileName: "Textures\specular.png" + RelativeFilename: "Textures\specular.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 2188262475552, "Texture::Glossiness", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Glossiness" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Glossiness" + FileName: "Textures\glossiness.png" + RelativeFilename: "Textures\glossiness.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 2188262480352, "Texture::Occlusion", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Occlusion" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Occlusion" + FileName: "Textures\occlusion.png" + RelativeFilename: "Textures\occlusion.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 2188262482752, "Texture::Normal", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Normal" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Normal" + FileName: "Textures\normal.png" + RelativeFilename: "Textures\normal.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 2188262481312, "Texture::Emission", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Emission" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Emission" + FileName: "Textures\emission.png" + RelativeFilename: "Textures\emission.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } + Texture: 2188262469792, "Texture::Opacity", "" { + Type: "TextureVideoClip" + Version: 202 + TextureName: "Texture::Opacity" + Properties70: { + P: "UVSet", "KString", "", "", "UVChannel_1" + P: "UseMaterial", "bool", "", "",1 + } + Media: "Video::Opacity" + FileName: "Textures\opacity.png" + RelativeFilename: "Textures\opacity.png" + ModelUVTranslation: 0,0 + ModelUVScaling: 1,1 + Texture_Alpha_Source: "None" + Cropping: 0,0,0,0 + } +} + +; Object connections +;------------------------------------------------------------------ + +Connections: { + + ;Model::Box001, Model::RootNode + C: "OO",2188763600256,0 + + ;Geometry::, Model::Box001 + C: "OO",2188631051296,2188763600256 + + ;Material::02 - Default, Model::Box001 + C: "OO",2188661245104,2188763600256 + + ;Texture::Albedo, Material::02 - Default + C: "OP",2188262484672,2188661245104, "3dsMax|main|base_color_map" + + ;Texture::Specular, Material::02 - Default + C: "OP",2188262499552,2188661245104, "3dsMax|main|specular_map" + + ;Texture::Glossiness, Material::02 - Default + C: "OP",2188262475552,2188661245104, "3dsMax|main|glossiness_map" + + ;Texture::Occlusion, Material::02 - Default + C: "OP",2188262480352,2188661245104, "3dsMax|main|ao_map" + + ;Texture::Normal, Material::02 - Default + C: "OP",2188262482752,2188661245104, "3dsMax|main|norm_map" + + ;Texture::Emission, Material::02 - Default + C: "OP",2188262481312,2188661245104, "3dsMax|main|emit_color_map" + + ;Texture::Opacity, Material::02 - Default + C: "OP",2188262469792,2188661245104, "3dsMax|main|opacity_map" + + ;Video::Albedo, Texture::Albedo + C: "OO",2188262470272,2188262484672 + + ;Video::Specular, Texture::Specular + C: "OO",2188262470752,2188262499552 + + ;Video::Glossiness, Texture::Glossiness + C: "OO",2188262476032,2188262475552 + + ;Video::Occlusion, Texture::Occlusion + C: "OO",2188262483232,2188262480352 + + ;Video::Normal, Texture::Normal + C: "OO",2188262486112,2188262482752 + + ;Video::Emission, Texture::Emission + C: "OO",2188262486592,2188262481312 + + ;Video::Opacity, Texture::Opacity + C: "OO",2188262687712,2188262469792 +} diff --git a/test/unit/utFBXImporterExporter.cpp b/test/unit/utFBXImporterExporter.cpp index 2f1ea79e8..88fda49cd 100644 --- a/test/unit/utFBXImporterExporter.cpp +++ b/test/unit/utFBXImporterExporter.cpp @@ -317,3 +317,109 @@ TEST_F(utFBXImporterExporter, importCubesWithOutOfRangeFloat) { ASSERT_NE(nullptr, scene); ASSERT_TRUE(scene->mRootNode); } + +TEST_F(utFBXImporterExporter, importMaxPbrMaterialsMetalRoughness) { + Assimp::Importer importer; + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/maxPbrMaterial_metalRough.fbx", aiProcess_ValidateDataStructure); + ASSERT_NE(nullptr, scene); + ASSERT_TRUE(scene->mRootNode); + + ASSERT_EQ(scene->mNumMaterials, 1); + const aiMaterial* mat = scene->mMaterials[0]; + aiString texture; + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_BASE_COLOR, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\albedo.png")); + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_METALNESS, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\metalness.png")); + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_EMISSION_COLOR, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\emission.png")); + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_NORMAL_CAMERA, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\normal.png")); + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_DIFFUSE_ROUGHNESS, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\roughness.png")); + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_AMBIENT_OCCLUSION, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\occlusion.png")); + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_OPACITY, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\opacity.png")); + + // The material contains values for standard properties (e.g. SpecularColor), where 3ds Max has presumably + // used formulas to map the Pbr values into the standard material model. However, the pbr values themselves + // are available in the material as untyped "raw" properties. We check that these are correctly parsed: + + aiColor4D baseColor; + ASSERT_EQ(mat->Get("$raw.3dsMax|main|basecolor", aiTextureType_NONE, 0, baseColor), aiReturn_SUCCESS); + EXPECT_EQ(baseColor, aiColor4D(0, 1, 1, 1)); + + float metalness; + ASSERT_EQ(mat->Get("$raw.3dsMax|main|metalness", aiTextureType_NONE, 0, metalness), aiReturn_SUCCESS); + EXPECT_EQ(metalness, 0.25f); + + float roughness; + ASSERT_EQ(mat->Get("$raw.3dsMax|main|roughness", aiTextureType_NONE, 0, roughness), aiReturn_SUCCESS); + EXPECT_EQ(roughness, 0.5f); + + int useGlossiness; + ASSERT_EQ(mat->Get("$raw.3dsMax|main|useGlossiness", aiTextureType_NONE, 0, useGlossiness), aiReturn_SUCCESS); + EXPECT_EQ(useGlossiness, 2); // AFAICT 1 = Roughness map is glossiness, 2 = Roughness map is roughness. + + float bumpMapAmt; // Presumably amount. + ASSERT_EQ(mat->Get("$raw.3dsMax|main|bump_map_amt", aiTextureType_NONE, 0, bumpMapAmt), aiReturn_SUCCESS); + EXPECT_EQ(bumpMapAmt, 0.75f); + + aiColor4D emitColor; + ASSERT_EQ(mat->Get("$raw.3dsMax|main|emit_color", aiTextureType_NONE, 0, emitColor), aiReturn_SUCCESS); + EXPECT_EQ(emitColor, aiColor4D(1, 1, 0, 1)); +} + +TEST_F(utFBXImporterExporter, importMaxPbrMaterialsSpecularGloss) { + Assimp::Importer importer; + const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/FBX/maxPbrMaterial_specGloss.fbx", aiProcess_ValidateDataStructure); + ASSERT_NE(nullptr, scene); + ASSERT_TRUE(scene->mRootNode); + + ASSERT_EQ(scene->mNumMaterials, 1); + const aiMaterial* mat = scene->mMaterials[0]; + aiString texture; + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_BASE_COLOR, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\albedo.png")); + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_SPECULAR, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\specular.png")); + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_EMISSION_COLOR, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\emission.png")); + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_NORMAL_CAMERA, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\normal.png")); + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_SHININESS, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\glossiness.png")); + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_AMBIENT_OCCLUSION, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\occlusion.png")); + ASSERT_EQ(mat->Get(AI_MATKEY_TEXTURE(aiTextureType_OPACITY, 0), texture), AI_SUCCESS); + EXPECT_EQ(texture, aiString("Textures\\opacity.png")); + + // The material contains values for standard properties (e.g. SpecularColor), where 3ds Max has presumably + // used formulas to map the Pbr values into the standard material model. However, the pbr values themselves + // are available in the material as untyped "raw" properties. We check that these are correctly parsed: + + aiColor4D baseColor; + ASSERT_EQ(mat->Get("$raw.3dsMax|main|basecolor", aiTextureType_NONE, 0, baseColor), aiReturn_SUCCESS); + EXPECT_EQ(baseColor, aiColor4D(0, 1, 1, 1)); + + aiColor4D specular; + ASSERT_EQ(mat->Get("$raw.3dsMax|main|Specular", aiTextureType_NONE, 0, specular), aiReturn_SUCCESS); + EXPECT_EQ(specular, aiColor4D(1, 1, 0, 1)); + + float glossiness; + ASSERT_EQ(mat->Get("$raw.3dsMax|main|glossiness", aiTextureType_NONE, 0, glossiness), aiReturn_SUCCESS); + EXPECT_EQ(glossiness, 0.33f); + + int useGlossiness; + ASSERT_EQ(mat->Get("$raw.3dsMax|main|useGlossiness", aiTextureType_NONE, 0, useGlossiness), aiReturn_SUCCESS); + EXPECT_EQ(useGlossiness, 1); // AFAICT 1 = Glossiness map is glossiness, 2 = Glossiness map is roughness. + + float bumpMapAmt; // Presumably amount. + ASSERT_EQ(mat->Get("$raw.3dsMax|main|bump_map_amt", aiTextureType_NONE, 0, bumpMapAmt), aiReturn_SUCCESS); + EXPECT_EQ(bumpMapAmt, 0.66f); + + aiColor4D emitColor; + ASSERT_EQ(mat->Get("$raw.3dsMax|main|emit_color", aiTextureType_NONE, 0, emitColor), aiReturn_SUCCESS); + EXPECT_EQ(emitColor, aiColor4D(1, 0, 1, 1)); +}