jkvargas / russimp

Assimp bindings for Rust
Other
84 stars 27 forks source link

Scene materials do not contain textures #48

Closed junglie85 closed 1 year ago

junglie85 commented 1 year ago

Hey. I'm working on a port of the learnopengl tutorial samples to wgpu and am a bit stuck on the model loading section. My implementation is failing because no textures are being found.

.mtl file:

# Blender MTL File: 'None'
# Material Count: 1

newmtl Scene_-_Root
Ns 225.000000
Ka 1.000000 1.000000 1.000000
Kd 0.800000 0.800000 0.800000
Ks 0.500000 0.500000 0.500000
Ke 0.0 0.0 0.0
Ni 1.450000
d 1.000000
illum 2
map_Kd diffuse.jpg
map_Bump normal.png
map_Ks specular.jpg

Scene materials:

[samples/model-loading/main.rs:301] &scene.materials = [
    Material {
        properties: [
            MaterialProperty {
                key: "?mat.name",
                data: String(
                    "DefaultMaterial",
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$mat.shadingm",
                data: IntegerArray(
                    [
                        2,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$mat.illum",
                data: IntegerArray(
                    [
                        1,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$clr.ambient",
                data: FloatArray(
                    [
                        0.0,
                        0.0,
                        0.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$clr.diffuse",
                data: FloatArray(
                    [
                        0.6,
                        0.6,
                        0.6,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$clr.specular",
                data: FloatArray(
                    [
                        0.0,
                        0.0,
                        0.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$clr.emissive",
                data: FloatArray(
                    [
                        0.0,
                        0.0,
                        0.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$mat.shininess",
                data: FloatArray(
                    [
                        0.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$mat.opacity",
                data: FloatArray(
                    [
                        1.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$clr.transparent",
                data: FloatArray(
                    [
                        1.0,
                        1.0,
                        1.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$mat.anisotropyFactor",
                data: FloatArray(
                    [
                        0.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$mat.refracti",
                data: FloatArray(
                    [
                        1.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
        ],
        textures: {},
    },
    Material {
        properties: [
            MaterialProperty {
                key: "?mat.name",
                data: String(
                    "Scene_-_Root",
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$mat.shadingm",
                data: IntegerArray(
                    [
                        2,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$mat.illum",
                data: IntegerArray(
                    [
                        1,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$clr.ambient",
                data: FloatArray(
                    [
                        0.0,
                        0.0,
                        0.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$clr.diffuse",
                data: FloatArray(
                    [
                        0.6,
                        0.6,
                        0.6,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$clr.specular",
                data: FloatArray(
                    [
                        0.0,
                        0.0,
                        0.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$clr.emissive",
                data: FloatArray(
                    [
                        0.0,
                        0.0,
                        0.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$mat.shininess",
                data: FloatArray(
                    [
                        0.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$mat.opacity",
                data: FloatArray(
                    [
                        1.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$clr.transparent",
                data: FloatArray(
                    [
                        1.0,
                        1.0,
                        1.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$mat.anisotropyFactor",
                data: FloatArray(
                    [
                        0.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
            MaterialProperty {
                key: "$mat.refracti",
                data: FloatArray(
                    [
                        1.0,
                    ],
                ),
                index: 0,
                semantic: None,
            },
        ],
        textures: {},
    },
]

I'm loading the scene like so:

let buffer = assets::load(&path).expect("failed to load model data");
let scene = Scene::from_buffer(
    &buffer,
    vec![PostProcess::Triangulate, PostProcess::FlipUVs],
    "",
)
.expect("failed to load scene from model data");
jkvargas commented 1 year ago

can you, please, share your model and textures?

junglie85 commented 1 year ago

Of course. They’re here.

jkvargas commented 1 year ago

so, looking at your file it does not seem that your textures are embedded to the file but they are separated files. loading the file I can see in materials:

MaterialProperty {
                key: "$tex.file",
                data: String(
                    "normal.png",
                ),
                index: 0,
                semantic: Height,
            },

MaterialProperty {
                key: "$tex.file",
                data: String(
                    "specular.jpg",
                ),
                index: 0,
                semantic: Specular,
            },

MaterialProperty {
                key: "$tex.file",
                data: String(
                    "diffuse.jpg",
                ),
                index: 0,
                semantic: Diffuse,
            },

so you can load those files as your textures.

junglie85 commented 1 year ago

I posted the full debug output of the scene.materials so I’m a bit confused where you’re getting the MaterialProperties that contain the texture details. Could you elaborate?

Also, in the original example it looks like the properties come from what would be the textures field:

vector<Texture> loadMaterialTextures(aiMaterial *mat, aiTextureType type, string typeName)
{
    vector<Texture> textures;
    for(unsigned int i = 0; i < mat->GetTextureCount(type); i++)
    {
        aiString str;
        mat->GetTexture(type, i, &str);
        Texture texture;
        texture.id = TextureFromFile(str.C_Str(), directory);
        texture.type = typeName;
        texture.path = str;
        textures.push_back(texture);
    }
    return textures;
}

Should that not also be the case with russimp or have I misunderstood what’s happening here?

jkvargas commented 1 year ago

hey mate, this is the implementation I made to get the results I mentioned you. https://filebin.net/mdws6uro5d1mpn66 I believe you can use 7zip to extract it on windows.

russimp does not provide the same interface as the c++ implementation. if the texture is embedded to the model then russimp will provide you with its contents, otherwise you can read the file pointed by MaterialProperty.

mhbka commented 6 months ago

hi, i was also puzzled by this while going through the learnopengl tutorial on Rust. i know nothing about Assimp or model loading, but would it make sense to initialize a Texture with empty DataContent if it's not an embedded texture? perhaps even add an is_embedded field to Texture struct, so at least users know that the texture is detected but data isn't loaded.