ThreeJS 为 .obj 上传多个纹理
Posted
技术标签:
【中文标题】ThreeJS 为 .obj 上传多个纹理【英文标题】:ThreeJS Upload multiple textures for .obj 【发布时间】:2021-05-12 17:57:43 【问题描述】:所以我正在尝试上传一个 .obj 文件,该文件也有多个 .png 和 .jpg 文件,它们是它的纹理。问题是我不知道在上传这些纹理时如何处理它们。
到目前为止,这是我的代码:
var loader = new THREE.OBJLoader(manager);
loader.load(obj_path, function (obj)
model = obj;
modelWithTextures = true;
model.traverse( function ( child )
if ( child.isMesh ) child.material.map = texture;
);
var textureLoader = new THREE.TextureLoader( manager );
var i;
for (var i = 0; i < files.length; i++)
file = files[i];
console.log('Texture Files:' + files[i].name);
var texture = textureLoader.load(files[i].name);
renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
setCamera(model);
setSmooth(model);
model.position.set(0, 0, 0);
setBoundBox(model);
setPolarGrid(model);
setGrid(model);
setAxis(model);
scaleUp(model);
scaleDown(model);
fixRotation(model);
resetRotation(model);
selectedObject = model;
outlinePass.selectedObjects = [selectedObject];
outlinePass.enabled = false;
renderer.render( scene, camera );
scene.add(model);
);
如您所见,我正在使用 textureLoader,但不知道该怎么做。
我对 threeJS 和 3d 模型非常陌生。
任何帮助或建议将不胜感激。
谢谢。
【问题讨论】:
你的OBJ资产有对应的MTL文件吗? 不,它是一个没有 MTL 文件的 OBJ。另一个开发人员告诉我,我需要手动添加这些纹理。 能否请您先确定您的OBJ文件是否有纹理坐标? 是的,我的 obj 文件确实有纹理坐标,也有几个 png 文件就是它的纹理。 【参考方案1】:在您的代码中,您可能看不到太多内容,因为您在将模型添加到场景之前渲染了场景。您应该在进行任何更改后渲染场景(除非您有一个带有requestAnimationFrame
的渲染循环)。加载纹理也是异步的。使用 .load
方法的回调来更好地在加载完成时做出反应,例如触发render()
。
我会在model.traverse()
回调中加载纹理。但是您必须确定哪个纹理属于哪个网格。这取决于您的数据的结构。
var files = ['mesh1_tex.jpg', 'mesh2_tex.jpg'];
var loader = new THREE.OBJLoader( manager );
var textureLoader = new THREE.TextureLoader( manager );
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set( 0, 0, -100); // depends on the size and location of your loaded model
var renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
var scene = new THREE.Scene();
loader.load(obj_path, function ( model )
model.traverse( function ( child )
if ( child instanceof THREE.Mesh )
// here you have to find a way how to choose the correct texture for the mesh
// the following is just an example, how it could be done, but it depends on your data
const file = files.find( f => f === child.name + '_tex.jpg');
if (!file)
console.warn(`Couldn't find texture file.`);
return;
textureLoader.load(file, ( texture ) =>
child.material.map = texture;
child.material.needsupdate = true;
render(); // only if there is no render loop
);
);
scene.add( model );
camera.lookAt( model ); // depends on the location of your loaded model
render(); // only if there is no render loop
);
function render()
renderer.render( scene, camera );
免责声明:我只是写下了这段代码,没有经过测试。
【讨论】:
以上是关于ThreeJS 为 .obj 上传多个纹理的主要内容,如果未能解决你的问题,请参考以下文章