Three.js multiple materials on object loaded via OBJMTLLoader

前端 未结 2 893
闹比i
闹比i 2020-12-01 05:59

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

相关标签:
2条回答
  • 2020-12-01 06:33

    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

    0 讨论(0)
  • 2020-12-01 06:36

    Your loaded object has geometry (along with its vertices, faces and UVs) and material. Create ShaderMaterial that combines the textures in some way that suits you and create mesh with geometry from loaded object.

    Use ShaderMaterial and set both textures as uniforms, and then blend them within shader.

    So, you make ShaderMaterial:

    var vertShader = document.getElementById('vertex_shh').innerHTML;
    var fragShader = document.getElementById('fragment_shh').innerHTML;
    
    var attributes = {}; // custom attributes
    
    var uniforms = {    // custom uniforms (your textures)
    
      tOne: { type: "t", value: THREE.ImageUtils.loadTexture( "cover.png" ) },
      tSec: { type: "t", value: THREE.ImageUtils.loadTexture( "grass.jpg" ) }
    
    };
    
    var material_shh = new THREE.ShaderMaterial({
    
      uniforms: uniforms,
      attributes: attributes,
      vertexShader: vertShader,
      fragmentShader: fragShader
    
    });
    

    And create mesh with that material:

    var me = new THREE.Mesh( my_loaded_model, material_shh ); // you previously loaded geometry of the object
    

    You can put simplest vertex shader:

    varying vec2 vUv;
    
    void main()
    {
        vUv = uv;
        vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
        gl_Position = projectionMatrix * mvPosition;
    }
    

    And fragment shader that will actually do the blending:

    #ifdef GL_ES
    precision highp float;
    #endif
    
    uniform sampler2D tOne;
    uniform sampler2D tSec;
    
    varying vec2 vUv;
    
    void main(void)
    {
        vec3 c;
        vec4 Ca = texture2D(tOne, vUv);
        vec4 Cb = texture2D(tSec, vUv);
        c = Ca.rgb * Ca.a + Cb.rgb * Cb.a * (1.0 - Ca.a);  // blending equation or wahtever suits you
        gl_FragColor= vec4(c, 1.0);
    }
    
    0 讨论(0)
提交回复
热议问题