Implemented basic texture mapping for PBR material definitions

This reads materials properly from Maya and expands on existing functionality to make this work properly.

aiTextureType_SHININESS no longer used as not appropriate for PBR texture as it is legacy.

This fix will be also present in assimp soon.
This commit is contained in:
RevoluPowered 2019-09-06 21:52:00 +01:00
parent a1fcac6400
commit efd6f6dbad
5 changed files with 119 additions and 34 deletions

View file

@ -679,6 +679,26 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
// cull all back faces // cull all back faces
mat->set_cull_mode(SpatialMaterial::CULL_BACK); mat->set_cull_mode(SpatialMaterial::CULL_BACK);
// Now process materials
aiTextureType base_color = aiTextureType_BASE_COLOR;
{
String filename, path;
AssimpImageData image_data;
if (AssimpUtils::GetAssimpTexture(state, ai_material, base_color, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
// anything transparent must be culled
if (image_data.raw_image->detect_alpha() != Image::ALPHA_NONE) {
mat->set_feature(SpatialMaterial::FEATURE_TRANSPARENT, true);
mat->set_depth_draw_mode(SpatialMaterial::DepthDrawMode::DEPTH_DRAW_ALPHA_OPAQUE_PREPASS);
mat->set_cull_mode(SpatialMaterial::CULL_DISABLED); // since you can see both sides in transparent mode
}
mat->set_texture(SpatialMaterial::TEXTURE_ALBEDO, image_data.texture);
}
}
// Now process materials // Now process materials
aiTextureType tex_diffuse = aiTextureType_DIFFUSE; aiTextureType tex_diffuse = aiTextureType_DIFFUSE;
{ {
@ -731,6 +751,60 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
} }
} }
aiTextureType tex_normal_camera = aiTextureType_NORMAL_CAMERA;
{
String filename, path;
Ref<ImageTexture> texture;
AssimpImageData image_data;
// Process texture normal map
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_normal_camera, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture);
}
}
aiTextureType tex_emission_color = aiTextureType_EMISSION_COLOR;
{
String filename, path;
Ref<ImageTexture> texture;
AssimpImageData image_data;
// Process texture normal map
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_emission_color, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
mat->set_feature(SpatialMaterial::Feature::FEATURE_NORMAL_MAPPING, true);
mat->set_texture(SpatialMaterial::TEXTURE_NORMAL, image_data.texture);
}
}
aiTextureType tex_metalness = aiTextureType_METALNESS;
{
String filename, path;
Ref<ImageTexture> texture;
AssimpImageData image_data;
// Process texture normal map
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_metalness, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
mat->set_texture(SpatialMaterial::TEXTURE_METALLIC, image_data.texture);
}
}
aiTextureType tex_roughness = aiTextureType_DIFFUSE_ROUGHNESS;
{
String filename, path;
Ref<ImageTexture> texture;
AssimpImageData image_data;
// Process texture normal map
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_roughness, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
mat->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, image_data.texture);
}
}
aiTextureType tex_emissive = aiTextureType_EMISSIVE; aiTextureType tex_emissive = aiTextureType_EMISSIVE;
{ {
String filename = ""; String filename = "";
@ -772,19 +846,6 @@ Ref<Mesh> EditorSceneImporterAssimp::_generate_mesh_from_surface_indices(
} }
} }
aiTextureType tex_roughness = aiTextureType_SHININESS;
{
String filename, path;
Ref<ImageTexture> texture;
AssimpImageData image_data;
// Process texture normal map
if (AssimpUtils::GetAssimpTexture(state, ai_material, tex_roughness, filename, path, image_data)) {
AssimpUtils::set_texture_mapping_mode(image_data.map_mode, image_data.texture);
mat->set_texture(SpatialMaterial::TEXTURE_ROUGHNESS, image_data.texture);
}
}
Array array_mesh = st->commit_to_arrays(); Array array_mesh = st->commit_to_arrays();
Array morphs; Array morphs;
morphs.resize(ai_mesh->mNumAnimMeshes); morphs.resize(ai_mesh->mNumAnimMeshes);

View file

@ -78,7 +78,7 @@ namespace Assimp {
#define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L #define CONVERT_FBX_TIME(time) static_cast<double>(time) / 46186158000L
FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit ) FBXConverter::FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones )
: defaultMaterialIndex() : defaultMaterialIndex()
, lights() , lights()
, cameras() , cameras()
@ -90,8 +90,7 @@ namespace Assimp {
, mNodeNames() , mNodeNames()
, anim_fps() , anim_fps()
, out(out) , out(out)
, doc(doc) , doc(doc) {
, mCurrentUnit(FbxUnit::cm) {
// animations need to be converted first since this will // animations need to be converted first since this will
// populate the node_anim_chain_bits map, which is needed // populate the node_anim_chain_bits map, which is needed
// to determine which nodes need to be generated. // to determine which nodes need to be generated.
@ -2002,6 +2001,12 @@ namespace Assimp {
TrySetTextureProperties(out_mat, textures, "Maya|SpecularTexture", aiTextureType_SPECULAR, mesh); TrySetTextureProperties(out_mat, textures, "Maya|SpecularTexture", aiTextureType_SPECULAR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|FalloffTexture", aiTextureType_OPACITY, mesh); TrySetTextureProperties(out_mat, textures, "Maya|FalloffTexture", aiTextureType_OPACITY, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh); TrySetTextureProperties(out_mat, textures, "Maya|ReflectionMapTexture", aiTextureType_REFLECTION, mesh);
// Maya PBR
TrySetTextureProperties(out_mat, textures, "Maya|baseColor|file", aiTextureType_BASE_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|normalCamera|file", aiTextureType_NORMAL_CAMERA, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|emissionColor|file", aiTextureType_EMISSION_COLOR, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|metalness|file", aiTextureType_METALNESS, mesh);
TrySetTextureProperties(out_mat, textures, "Maya|diffuseRoughness|file", aiTextureType_DIFFUSE_ROUGHNESS, mesh);
} }
void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh) void FBXConverter::SetTextureProperties(aiMaterial* out_mat, const LayeredTextureMap& layeredTextures, const MeshGeometry* const mesh)
@ -3589,9 +3594,9 @@ void FBXConverter::SetShadingPropertiesRaw(aiMaterial* out_mat, const PropertyTa
} }
// ------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit) void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones)
{ {
FBXConverter converter(out, doc, removeEmptyBones, unit); FBXConverter converter(out, doc, removeEmptyBones);
} }
} // !FBX } // !FBX

View file

@ -92,7 +92,7 @@ enum class FbxUnit {
* @param doc Parsed FBX document * @param doc Parsed FBX document
* @param removeEmptyBones Will remove bones, which do not have any references to vertices. * @param removeEmptyBones Will remove bones, which do not have any references to vertices.
*/ */
void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit); void ConvertToAssimpScene(aiScene* out, const Document& doc, bool removeEmptyBones);
/** Dummy class to encapsulate the conversion process */ /** Dummy class to encapsulate the conversion process */
class FBXConverter { class FBXConverter {
@ -123,7 +123,7 @@ public:
}; };
public: public:
FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones, FbxUnit unit); FBXConverter(aiScene* out, const Document& doc, bool removeEmptyBones);
~FBXConverter(); ~FBXConverter();
private: private:

View file

@ -191,7 +191,7 @@ void FBXImporter::InternReadFile( const std::string& pFile, aiScene* pScene, IOS
} }
// convert the FBX DOM to aiScene // convert the FBX DOM to aiScene
ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones, unit); ConvertToAssimpScene(pScene, doc, settings.removeEmptyBones);
// size relative to cm // size relative to cm
float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor(); float size_relative_to_cm = doc.GlobalSettings().UnitScaleFactor();

View file

@ -196,34 +196,40 @@ enum aiTextureType
* (#aiMaterialProperty::mSemantic) for all material properties * (#aiMaterialProperty::mSemantic) for all material properties
* *not* related to textures. * *not* related to textures.
*/ */
aiTextureType_NONE = 0x0, aiTextureType_NONE = 0,
/** LEGACY API MATERIALS
* Legacy refers to materials which
* Were originally implemented in the specifications around 2000.
* These must never be removed, as most engines support them.
*/
/** The texture is combined with the result of the diffuse /** The texture is combined with the result of the diffuse
* lighting equation. * lighting equation.
*/ */
aiTextureType_DIFFUSE = 0x1, aiTextureType_DIFFUSE = 1,
/** The texture is combined with the result of the specular /** The texture is combined with the result of the specular
* lighting equation. * lighting equation.
*/ */
aiTextureType_SPECULAR = 0x2, aiTextureType_SPECULAR = 2,
/** The texture is combined with the result of the ambient /** The texture is combined with the result of the ambient
* lighting equation. * lighting equation.
*/ */
aiTextureType_AMBIENT = 0x3, aiTextureType_AMBIENT = 3,
/** The texture is added to the result of the lighting /** The texture is added to the result of the lighting
* calculation. It isn't influenced by incoming light. * calculation. It isn't influenced by incoming light.
*/ */
aiTextureType_EMISSIVE = 0x4, aiTextureType_EMISSIVE = 4,
/** The texture is a height map. /** The texture is a height map.
* *
* By convention, higher gray-scale values stand for * By convention, higher gray-scale values stand for
* higher elevations from the base height. * higher elevations from the base height.
*/ */
aiTextureType_HEIGHT = 0x5, aiTextureType_HEIGHT = 5,
/** The texture is a (tangent space) normal-map. /** The texture is a (tangent space) normal-map.
* *
@ -231,7 +237,7 @@ enum aiTextureType
* normal maps. Assimp does (intentionally) not * normal maps. Assimp does (intentionally) not
* distinguish here. * distinguish here.
*/ */
aiTextureType_NORMALS = 0x6, aiTextureType_NORMALS = 6,
/** The texture defines the glossiness of the material. /** The texture defines the glossiness of the material.
* *
@ -240,21 +246,21 @@ enum aiTextureType
* function defined to map the linear color values in the * function defined to map the linear color values in the
* texture to a suitable exponent. Have fun. * texture to a suitable exponent. Have fun.
*/ */
aiTextureType_SHININESS = 0x7, aiTextureType_SHININESS = 7,
/** The texture defines per-pixel opacity. /** The texture defines per-pixel opacity.
* *
* Usually 'white' means opaque and 'black' means * Usually 'white' means opaque and 'black' means
* 'transparency'. Or quite the opposite. Have fun. * 'transparency'. Or quite the opposite. Have fun.
*/ */
aiTextureType_OPACITY = 0x8, aiTextureType_OPACITY = 8,
/** Displacement texture /** Displacement texture
* *
* The exact purpose and format is application-dependent. * The exact purpose and format is application-dependent.
* Higher color values stand for higher vertex displacements. * Higher color values stand for higher vertex displacements.
*/ */
aiTextureType_DISPLACEMENT = 0x9, aiTextureType_DISPLACEMENT = 9,
/** Lightmap texture (aka Ambient Occlusion) /** Lightmap texture (aka Ambient Occlusion)
* *
@ -263,14 +269,27 @@ enum aiTextureType
* scaling value for the final color value of a pixel. Its * scaling value for the final color value of a pixel. Its
* intensity is not affected by incoming light. * intensity is not affected by incoming light.
*/ */
aiTextureType_LIGHTMAP = 0xA, aiTextureType_LIGHTMAP = 10,
/** Reflection texture /** Reflection texture
* *
* Contains the color of a perfect mirror reflection. * Contains the color of a perfect mirror reflection.
* Rarely used, almost never for real-time applications. * Rarely used, almost never for real-time applications.
*/ */
aiTextureType_REFLECTION = 0xB, aiTextureType_REFLECTION = 11,
/** PBR Materials
* PBR definitions from maya and other modelling packages now use this standard.
* This was originally introduced around 2012.
* Support for this is in game engines like Godot, Unreal or Unity3D.
* Modelling packages which use this are very common now.
*/
aiTextureType_BASE_COLOR = 12,
aiTextureType_NORMAL_CAMERA = 13,
aiTextureType_EMISSION_COLOR = 14,
aiTextureType_METALNESS = 15,
aiTextureType_DIFFUSE_ROUGHNESS = 16,
/** Unknown texture /** Unknown texture
* *
@ -278,7 +297,7 @@ enum aiTextureType
* above is considered to be 'unknown'. It is still imported, * above is considered to be 'unknown'. It is still imported,
* but is excluded from any further post-processing. * but is excluded from any further post-processing.
*/ */
aiTextureType_UNKNOWN = 0xC, aiTextureType_UNKNOWN = 17,
#ifndef SWIG #ifndef SWIG