如何使用jsc3d中的多个纹理将纹理指定给OBJ文件

时间:2015-09-26 00:44:31

标签: 3d textures jsc3d

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

感谢您的帮助

1 个答案:

答案 0 :(得分:3)

让我们从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会动态重新创建它们:

enter image description here

对不起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");
}

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

enter image description here

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

修改

replaceBlueTexture函数假设您已经知道应该替换哪个网格。

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

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

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

enter image description here

你需要的只是检查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");
        }
    }
}

BTW,请确保渲染模式可以显示纹理:

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