Assimp不会导入纹理

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Assimp不会导入纹理相关的知识,希望对你有一定的参考价值。

我正在使用assimp在我的游戏引擎中导入3d模型。出于某种原因,无论我使用何种型号或型号格式,assimp都不会报告任何纹理。为什么是这样?

以下是assimp非常简单的设置:

const aiScene* scene = importer.ReadFile(asset, aiProcessPreset_TargetRealtime_Quality);

if (scene->HasMaterials())
        {
            for (unsigned int i = 0; i < scene->mNumMaterials; i++)
            {
                const aiMaterial* material = scene->mMaterials[i];
                aiString texturePath;

                unsigned int numTextures= material->GetTextureCount(aiTextureType_DIFFUSE);   // always 0

                if (material->GetTextureCount(aiTextureType_DIFFUSE) > 0 && material->GetTexture(aiTextureType_DIFFUSE, 0, &texturePath) == AI_SUCCESS) 
                {
                   // never happens..
                   // scene->mNumTextures is always 0 aswell.
                }
            }
        }

我正在使用各种模型,我肯定有纹理,例如教程中的模型是为使用assimp加载纹理模型的非常具体的原因而设计的。 (例如,http://www.lighthouse3d.com/cg-topics/code-samples/importing-3d-models-with-assimp

这可能是什么原因?

答案

我知道这已经很老了,但过去几天我遇到了这个确切的问题,并设法弄明白了,所以这里有一个解决方案,无论是谁在寻找。

纹理未加载的原因有两个:

  1. 纹理是嵌入的。

要么

  1. 您的模型的材料文件有问题。

如果它是#1的情况,那么它就不起作用,因为GetTexture和GetTextureCount不适用于嵌入式材料。嵌入式材料通常只是简单的颜色。如果您想知道如何导入嵌入材料,请查看ASSIMP示例代码或AssimpView的源代码。

机密是你的问题#2:你的材料文件有问题。例如,.OBJ模型文件带有相应的.MTL文件,如果它们是纹理的。如果缺少.MTL文件,则不会加载纹理。如果.MTL文件有问题,纹理也不会加载。

因此,请确保所有.mtl文件都在那里以及任何其他材质文件(包括纹理本身的图像)。如果它们在那里,那么接下来你要做的就是使用AssimpView工具打开模型。确保模型正确加载其所有纹理。如果没有,那么材料文件(下面的解决方案)出现问题,或者模型文件出现问题,而Assimp根本无法加载它(或者Assimp的根本错误)。如果正确加载,您应该在AssimpView的右侧看到漫反射纹理的名称。

因此,如果所有这些都检出并且程序中的Assimp导入器仍然无法识别模型中的纹理(即使AssimpView确实如此),那么您要做的下一件事实际上是使用记事本之类的东西打开.MTL文件。你会看到这样的事情:

# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 06.10.2013 19:40:35

newmtl 01___Default
Ns 10.0000
illum 2
Ka 0.0000 0.0000 0.0000
Kd 0.5882 0.5882 0.5882
Ks 0.0000 0.0000 0.0000
Ni 1
d 0
map_Kd MoonMap2_2500x1250.jpg

这些文件有各种各样的错误。请注意,map_Kd定义了用于漫反射贴图的图像文件。有时候,你不会在那里找到正确的路径或文件名,而是看到相对于制作模型的计算机的整个目录路径(即它会说像C:/ Users / blah blah blah / MoonMap2 ...)。您可以通过删除目录路径并仅保留图像文件名(并将图像保持在与模型相同的文件夹中)来轻松解决此问题,或者您可以放置​​自己的自定义路径并将纹理放在那里。

您可能会看到的另一类问题是.MTL文件中列出的变量实际上没有给定值。

例如:

# 3ds Max Wavefront OBJ Exporter v0.97b - (c)2007 guruware
# File Created: 06.10.2013 19:40:35

newmtl 01___Default
Ns 10.0000
illum 2
Ka 0.0000 0.0000 0.0000
Kd 0.5882 0.5882 0.5882
Ks 0.0000 0.0000 0.0000
Ni 1
d 0
map_Kd MoonMap2_2500x1250.jpg
map_Ka 

注意那里的“map_Ka”。它旁边没有任何东西。这不仅可以防止纹理被正确识别,而且实际上阻止了AssimpView能够加载模型。只需删除它们旁边没有值时所见的任何属性。

最后,如果这些都不起作用,那么你可能只需要试验.MTL文件 - 可能有一个属性/变量列在其中由于某种原因导致麻烦,所以尝试删除你绝对确定不要的行不需要(注意Kd代表漫反射纹理,Ka代表环境纹理,Ks代表镜面反射等)。我在这里作为示例使用的.MTL文件包含我认为MTL文件应该具有的最小行,以便能够加载漫反射纹理。

希望这可以帮助。如果这些都不起作用,我会怀疑你的ASSIMP库存在根本性的错误。如果您的模型文件没有很好的材料文件......那就是您的问题。

另一答案

继续Matt所说的关于材料文件的有效性,我发现了另一个可能的问题,即材料没有加载并且是一个解决方案。

在obj文件中,引用了该文件中的材料文件和材料名称。如果您已重命名该文件,则这些文件将不匹配,并且找不到该材料。

在obj文件中,您将找到一个如下所示的行

mtllib deer-obj.mtl

这是材料文件的名称。如果您已重命名该材料,则必须在此处重命名。

在同一文件中,您将找到对材料文件中定义的材料名称的引用,如下所示:

usemtl deer

这必须匹配材料文件中材料的名称。在mtl文件中我定义了这个:

newmtl deer

“usemtl”名称和“newmtl”名称必须匹配才能找到材料。

另一答案

探索assimp源表明OBJ导入器中根本没有mNumTextures ++。因此,导入OBJ文件永远不会是积极的。

加载纹理的正确方法是添加到apply_material()的末尾(您可以在github上的assimp存储库中获取示例源代码)下一个代码(D语言):

aiString path;
if(aiReturn_SUCCESS == aiGetMaterialTexture(mtl, aiTextureType_DIFFUSE, 0, &path))
{
    string p = (cast(const(char)*)(path.data)).to!(string)();

    GLuint texture_name;
    glGenTextures(1, &texture_name);// generate GL-textures ID's
    glBindTexture(GL_TEXTURE_2D, texture_name);// Binding of texture name
    //
    //redefine standard texture values
    //
    // We will use linear interpolation for magnification filter
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    // tiling mode
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, true ? GL_REPEAT : GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, true ? GL_REPEAT : GL_CLAMP);

    auto image = IMG_Load(p.toStringz);
    if (!image)
    {
        throw new Exception(format("Error while loading texture: %s", p));
    }

    // Texture specification
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, image.w, image.h, 0, GL_RGBA, GL_UNSIGNED_BYTE,
            image.pixels);
}

并显示此纹理添加到glColor4fv和glNormal3fv之间的recursive_render()下一行:

glTexCoord2f(mesh.mTextureCoords[0][index].x, 1.0-mesh.mTextureCoords[0][index].y);

以上是关于Assimp不会导入纹理的主要内容,如果未能解决你的问题,请参考以下文章

使用 ASSIMP 和 OpenGL 加载 3D 模型时纹理不正确

Assimp 模型有纹理但没有纹理坐标

Assimp FBX 加载器和 PBR 纹理

Assimp 无法加载除 FBX 的漫反射纹理外的其他纹理

使用 VAO/VBO 进行 OpenGL 模型/纹理渲染

Assimp导入导出格式错误