我使用jsc3d查看器以.obj格式导入具有定义纹理的3d对象的组部分。我希望能够为每个单独的部分分配新的纹理。例如,我加载了我的.obj文件,包含10个不同的部分。所有的部分都是白色的。我有三个.png格式的纹理(红色,蓝色和绿色)。我想把纹理“红色”分配给一些部分,纹理“蓝色”和“绿色”分配给其他部分。我希望能够修改它们。怎么做?
谢谢你的帮忙
发布于 2015-09-29 17:51:35
让我们从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.00JSC3D将读取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个独立的部分,每个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");
}结果如下(加载后左右,纹理变化后右转):

现在,这个立方体的顶部和底部都是铝织构的。
编辑:
replaceBlueTexture函数假定您已经知道应该替换哪个网格。
如果你必须用一个网格的名字来替换它的材质(或者纹理)呢?
首先加载和解析obj文件,在obj文件之后加载mtl文件,但是在obj文件解析期间,jsc3d已经捕获并存储在网格对象中的材料名称。
如果您查看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');https://stackoverflow.com/questions/32792480
复制相似问题