Krz*_*ski 5 javascript three.js
我想加载cube.obj引用多个cube_*.mtl文件的文件,后者又使用纹理图像*.png(所有资源).加载多个mtl而不是一个mtl的原因是能够动态加载具有相同几何但不同材质的对象.
我找不到这样的例子所以我试图通过加载所有mtl,创建和加载obj 来混合MultiMaterial中的示例(不再受threejs支持)文档和webgl_loader_obj_mtlMultiMaterial:
var resources = 'cube/';
var materialsToLoad = [
'cube_red.mtl',
'cube_green.mtl',
'cube_blue.mtl'
];
var loadedMaterials = [];
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setPath(resources);
for (var i = 0; i < materialsToLoad.length; i++) {
mtlLoader.load(materialsToLoad[i], function(materials) {
materials.preload();
loadedMaterials.push(materials);
});
}
var multi = new THREE.MultiMaterial(loadedMaterials);
var objLoader = new THREE.OBJLoader();
objLoader.setPath(resources);
objLoader.setMaterials(multi); // #1
objLoader.load('cube.obj', function (object) {
scene.add(object);
});
Run Code Online (Sandbox Code Playgroud)
但这不起作用,抛出异常:
Uncaught TypeError: this.materials.create is not a function
at THREE.OBJLoader.parse (OBJLoader.js:684)
at OBJLoader.js:50
at XMLHttpRequest.<anonymous> (three.min.js:619)
Run Code Online (Sandbox Code Playgroud)
我做错了什么以及如何正确地做到这一点?
小智 0
我认为这里存在一些问题。
1) THREE.MTLLoader .load 表现为“非阻塞”函数。
因此,当 MTL 文件尚未完全加载时,您正在加载 OBJ 文件。您需要在mtlLoader.load()上作为参数传递的回调函数中加载 OBJ 文件。看看你提到的例子。
2) 关于作为参数传递的mtlLoader.load回调函数:
它的参数Materials 的类型为THREE.MTLLoader.MaterialCreator。因此,loadedMaterials是一个THREE.MTLLoader.MaterialCreator元素的数组,为了创建THREE.MultiMaterial(Three.MultiMaterial 不再受 Threejs 支持),您需要一个THREE.Material元素的数组。
此外,MultiMaterial 用于将多种材质分配给一个对象(每个对象的面一种材质),而不是用于“可选”为对象选择材质(MultiMaterial Cube 示例)。
执行此操作的一种方法(代码未测试):
首先,我们需要一个LoadingManager:
var manager = new THREE.LoadingManager();
Run Code Online (Sandbox Code Playgroud)
这是为了断言在加载 OBJ 之前所有 MTL 都已加载:
manager.onLoad = function() {
/*
At this point, all MTL's have been loaded.
We will load an OBJ with the first material option
(for example), if it exists.
*/
if (loadedMaterials.length > 0) {
var objLoader = new THREE.OBJLoader();
objLoader.setPath(resources);
objLoader.setMaterials(loadedMaterials[0]); // First material
objLoader.load('cube.obj', function (object) {
scene.add(object);
}
};
Run Code Online (Sandbox Code Playgroud)
我们加载所有 MTL:
var mtlLoader = new THREE.MTLLoader(manager);
mtlLoader.setPath(resources);
for (var i = 0; i < materialsToLoad.length; i++) {
mtlLoader.load(materialsToLoad[i], function(materials) {
materials.preload();
loadedMaterials.push(materials);
});
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你!