【问题标题】:How to assign a texture to an OBJ file using multiple textures in jsc3d如何在 jsc3d 中使用多个纹理将纹理分配给 OBJ 文件
【发布时间】:2015-12-23 21:27:36
【问题描述】:

我使用 jsc3d 查看器以 .obj 格式导入 3d 对象的一组部分,并定义了纹理。我希望能够为每个单独的部分分配新的纹理。 例如,我加载了我的 .obj 文件,其中包含 10 个不同的部分。所有部分都是完全白色的。我有 3 个 .png 格式的纹理(红色、蓝色和绿色)。我想将纹理“红色”分配给某些部分,将纹理“蓝色”和“绿色”分配给其他部分。我希望能够修改它们。该怎么做?

感谢您的帮助

【问题讨论】:

    标签: 3d textures jsc3d


    【解决方案1】:

    让我们从 obj 格式开始: 这是一个简单的立方体示例,在相对的面上应用了 3 种不同的纹理:

    # OBJ File Generated by Meshlab    
    # Vertices: 8
    # Faces: 12
    mtllib ./tex_cube.obj.mtl
    v -50.00 -50.00 50.00
    v -50.00 50.00 50.00
    v 50.00 -50.00 50.00
    v 50.00 50.00 50.00
    v 50.00 -50.00 -50.00
    v 50.00 50.00 -50.00
    v -50.00 -50.00 -50.00
    v -50.00 50.00 -50.00
    

    注意mtl文件的路径,大部分问题是因为找不到文件,还有一些3d工具不允许mtl文件或纹理的相对路径。 我建议你,把它和 obj 文件放在一起。

    有 12 个三角形,因为立方体的每一边都经过了三角剖分。 vt(顶点纹理)标签定义了纹理的映射方式,在这种情况下是通过 UV(对每个面很简单):

    vt 1.00 1.00
    vt 0.00 1.00
    vt 0.00 0.00
    vt 1.00 0.00
    

    JSC3D 将读取 vt 标签、f(faces)标签和 usemtl 标签来构建 3d 对象:

    usemtl material_0
    f 4/1 2/2 1/3
    f 3/4 4/1 1/3
    f 8/1 6/2 5/3
    f 7/4 8/1 5/3
    
    usemtl material_1
    f 6/1 4/2 3/3
    f 5/4 6/1 3/3
    f 2/1 8/2 7/3
    f 1/4 2/1 7/3
    
    usemtl material_2
    f 6/1 8/2 2/3
    f 4/4 6/1 2/3
    f 3/1 1/2 7/3
    f 5/4 3/1 7/3
    

    材质重新映射到mtl文件中对应的png文件:

    newmtl material_0
    Ka 0.200000 0.200000 0.200000
    Kd 1.000000 1.000000 1.000000
    Ks 1.000000 1.000000 1.000000
    map_Kd red_tex.png
    

    ...对于其他两个纹理,绿色和蓝色,依此类推。

    此文件是从 MeshLab 中的以下导出设置中获得的,只是指出您不需要导出法线,JSC3D 会即时重新创建它们:

    对于 obj 测试文件的无聊解释,请见谅。

    如果您在 JSC3D 查看器中加载这个立方体并检查 viewer.scene.children[],您会发现 3 个网格,因为 JSC3D 已将立方体的 12 个三角形分为 3 个单独的部分,每个部分一个在 obj 文件中找到的 usemtl 标签

    现在,您可以通过 PickInfo 结构通过在查看器中选择一个面(通过鼠标单击或触摸)或通过代码来获取其中一个部件的引用。

    例如,如果您需要将蓝色纹理替换为另一个:

    function replaceBlueTexture() {
        objParts = []; // you can also replace more than one part
        objParts[0] = viewer.scene.children[2];
        objLoader.setupTexture(objParts, "models/obj/aluminum.png");
    }
    

    结果如下(加载后左右,纹理更改后右):

    现在,这个立方体的顶面和底面都是铝质感的。

    编辑:

    replaceBlueTexture 函数假定您已经知道要替换哪个网格。

    如果您必须用名称替换网格的材质(或纹理)怎么办?

    obj文件先加载解析,mtl文件在obj文件之后加载,但是jsc3d在解析obj文件时已经将材质名称捕获并存储在Mesh对象中了。

    如果您查看 viewer.scene 对象,您将看到上述网格以及相关的材质和纹理:

    您只需要检查mesh.mtl(或者可能是mesh.material.name - 两者之一应填写最新版本的jsc3d):

    function replaceBlueTextureByName() {
        var scene = viewer.getScene();
        var meshes = scene.getChildren();
        for (var i=0, l=meshes.length; i<l; i++) {
            var mesh = meshes[i];
            var mat = mesh.material;
            if (mat.name == 'mat_blue_tex') {
                var objParts = [];
                objParts[0] = mesh;
                loader.setupTexture(objParts, "models/obj/aluminum.png");
            }
        }
    }
    

    顺便说一句,请确保渲染模式可以显示纹理:

    viewer.setParameter('RenderMode', 'texturesmooth');
    

    【讨论】:

    • 太棒了!我真的很感谢你的帮助。但我需要更多解释。关于MTL文件,如果我有这里面:newmtl BASIC_FABRIC_FRONT_15517嘉0.694256 0.694256 0.694256的Kd 0.748897 0.748897 0.748897 Ks的0.000000 0.000000 0.000000 Ns个5.000000 ILLUM 2 d 1.000000 newmtl Material15532嘉0.847059 0.847059 0.847059的Kd 0.913725 0.913725 0.913725 Ks的0.000000 0.000000 0.000000 Ns个5.000000 ILLUM 2 d 1.000000。如何按名称选择材质(比如说 newmtl Material15532)并在其上应用纹理???
    • 嗨,Al vlad,澄清问题:您只有在您的 mtl 文件中定义的材料,而不是纹理,因为纹理是图像文件,例如例如映射到材质的 png 或 jpg。查看我的编辑。
    猜你喜欢
    • 2018-10-12
    • 1970-01-01
    • 2020-10-05
    • 2017-10-04
    • 2012-03-07
    • 2015-08-30
    • 2017-10-03
    • 2021-07-20
    • 2018-10-18
    相关资源
    最近更新 更多