通过 OBJMTLLoader 加载对象上的 Three.js 多种材料 [英] Three.js multiple materials on object loaded via OBJMTLLoader

查看:71
本文介绍了通过 OBJMTLLoader 加载对象上的 Three.js 多种材料的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个模型的.obj"和.mtl"文件,我正在通过 OBJMTLLoader 加载它..mtl"指定要应用于模型的纹理,而three.js加载模型并使用应用的纹理渲染它就好了.

I have ".obj" and ".mtl" files of a model and I'm loading it via OBJMTLLoader. ".mtl" specifies texture to apply to a model, and three.js loads model and renders it with applied texture just fine.

但事情就是这样.

一旦一个对象被加载,我想在它上面应用另一个纹理.这是因为第一个纹理代表对象的表面材料.第二个纹理是绘图,我想将其放置在模型的特定位置.

Once an object is loaded, I would like to apply another texture onto it. This is because first texture represents surface material of an object. And second texture is a drawing, that I'd like to position at a specific location on a model.

我的问题是:如何将第二个纹理应用到已加载(和纹理化)的对象上?

我看到three.js创建了一个THREE.Object3D的实例,并且该实例有一个带有THREE.Mesh实例的children"数组.

I see that three.js creates an instance of THREE.Object3D, and that instance has "children" array with one instance of THREE.Mesh.

当我尝试将纹理应用于该网格时(mesh.material.map = texture),我丢失了初始纹理.

When I try to apply a texture to that mesh (mesh.material.map = texture), I lose initial texture.

我调查了这个有关应用多个纹理和 JSONLoader 的问题,但没有找到回答.

I looked into this question about applying multiple textures and JSONLoader but didn't find an answer.

我也尝试使用 new THREE.MeshFaceMaterial( materials )(如 这个答案中的建议) 但没有成功.

I also tried using new THREE.MeshFaceMaterial( materials ) (as suggested in this answer) but unsuccessfully.

更新:

我尝试了@WestLangley 的使用多材质对象的建议,但仍然无法在另一种材质之上渲染一种材质.

I tried @WestLangley's suggestion to use multi-material object, but am still unable to render one material on top of another one.

我做了这个简单的演示,改编自three.js OBJLoader — http://dl.dropboxusercontent.com/u/822184/webgl_multiple_texture/index.html

I made this simple demo, adapted from three.js OBJLoader — http://dl.dropboxusercontent.com/u/822184/webgl_multiple_texture/index.html

我按照建议使用 THREE.SceneUtils.createMultiMaterialObject,将其从 .obj 加载的主网格的克隆几何传递给它.我还为它提供了 2 个纹理——一个用于整个表面,另一个用于模型的前表面.

I'm using THREE.SceneUtils.createMultiMaterialObject as suggested, passing it cloned geometry of main mesh loaded from .obj. I'm also giving it 2 textures — one for entire surface, another one — for front surface of the model.

但这行不通.我添加了 2 个复选框来切换相应材料的可见"属性.您可以看到材料存在,但我无法从第二个下方看到第一个.

But this doesn't work. I added 2 checkboxes that toggle "visible" property of corresponding materials. You can see that materials are present, but I can't see the first one from beneath second one.

加载/渲染的关键如下:

The crux of the loading/rendering is as follows:

var texture = THREE.ImageUtils.loadTexture('fabric.jpg');
var texture2 = THREE.ImageUtils.loadTexture('table.jpg');

texture2.offset.set(-0.65, -2.5);
texture2.repeat.set(4, 4);

var loader = new THREE.OBJLoader();
loader.addEventListener( 'load', function ( event ) {

  var mainMesh = event.content.children[0].children[0];

  multiMaterialObject = THREE.SceneUtils.createMultiMaterialObject( 
    mainMesh.geometry.clone(), [
      new THREE.MeshLambertMaterial({ map: texture2 }),
      new THREE.MeshLambertMaterial({ map: texture })
    ]);

  multiMaterialObject.position.y = -80;
  scene.add(multiMaterialObject);
});

loader.load( 'male02.obj' );

更新 #2

此时,我认为最好的办法是使用 THREE.ShaderMaterial 将一种纹理应用到另一种纹理上.我看到一些使用一种纹理的示例,但仍然不确定如何在叠加状态.我也不确定如何在网格上的特定位置定位纹理.

At this point, I think the best bet is to use THREE.ShaderMaterial to apply one texture onto another. I see some examples of using one texture but still unsure how to display both in overlaid state. I'm also not sure how to position texture at a specific location on a mesh.

推荐答案

您有多种选择:

  1. 您可以使用画布工具在 javascript 端混合图像,并使用单个纹理贴图创建单个材质.

  1. You can mix the images on the javascript side using canvas tools, and create a single material with a single texture map.

您可以从单个几何图形和一系列材料创建多材料对象.(这种方法只是创建多个相同的网格,每个网格都有一种材质,通常在其中一种材质是线框时使用.如果一种材质是透明的,它也可以正常工作.)

You can create a multi-material object from a single geometry and an array of materials. (This approach just creates multiple identical meshes, each with one of the materials, and usually is used when one of the materials is wireframe. It may also work OK if one material is transparent.)

THREE.SceneUtils.createMultiMaterialObject( geometry, materials);

您可以使用自定义ShaderMaterial 实现多纹理效果.有两个纹理输入,并在着色器中实现颜色混合.

You can achieve a multi-texture effect with a custom ShaderMaterial. Have two texture inputs, and implement color mixing in the shader.

这里是实现两种纹理混合的最简单的 Three.js ShaderMaterial 示例:https://jsfiddle.net/6bg4qdhx/3/.

Here an example of just about the simplest three.js ShaderMaterial possible that implements mixing of two textures: https://jsfiddle.net/6bg4qdhx/3/.

另见 在标准PBR着色器中是否有一种内置的方法来分层纹理?

three.js r.92

three.js r.92

这篇关于通过 OBJMTLLoader 加载对象上的 Three.js 多种材料的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆