Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
589 views
in Technique[技术] by (71.8m points)

javascript - Three.js multiple materials on object loaded via OBJMTLLoader

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.

But here's the thing.

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.

My question is: how to apply a second texture onto already loaded (and texturized) object?

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

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

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

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

UPDATE:

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

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

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.

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' );

UPDATE #2

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.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You have several choices:

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

  2. 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 );

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

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


EDIT: Also see Is there a built-in way to layer textures within the standard PBR shader?

three.js r.92


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...