2015-09-26 63 views
1

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

感谢您的帮助

回答

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(面)标签和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 

材料被重新映射到对应的PNG文件的MTL文件:

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个独立的部件,一个用于每个usemtl标签已在obj文件中找到。现在

,则可以通过选择观众内侧的面打通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文件首先被加载并解析,mtl文件被加载到obj文件后,但是在分析obj文件时,材质名已被jsc3d捕获并存储在Mesh对象中。

如果你看一下viewer.scene对象,你会看到上述的网格和相关的材料和质地:

enter image description here

你需要什么刚刚只检查mesh.mtl是(

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,确保渲染模式可以显示纹理:

- 或者也许是mesh.material.name两个人不得在最新版本jsc3d的)填写
viewer.setParameter('RenderMode', 'texturesmooth'); 
+0

太棒了!我非常感谢你的帮助。但我需要更多的解释。关于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)并在其上应用纹理? –

+0

Hi Al vlad,为了澄清这个问题:你只有材料在yout mtl文件中定义,而不是纹理,因为纹理是图像文件,例如图像。例如png或jpg映射到材质。看我的编辑。 – deblocker

相关问题