如何将纹理应用于脸部的一部分?

How to apply a texture to part of a face?

我只想将纹理应用于立方体表面的指定部分 - 而不是整个表面。我想对同一张脸多次这样做。比如我想把texture1.jpg放在人脸的右上角,texture2.jpg放在右下角,texture3.jpg放在左上角,texture4.jpg在中间.

我希望能够在不为每个部分创建新网格的情况下执行此操作。

我遇到了与必须为纹理的每个部分创建一个新网格相关的性能问题,如果我可以通过某种方式将 "decals" 放置在单个网格上来做到这一点,整个过程将 运行 更顺畅。

您可以自定义组合纹理 THREE.ShaderMAterial:

    <script id="cubeFragmentShader" type="x-shader/x-fragment">
        uniform vec2 aMin;
        uniform vec2 aMax;    
        varying vec2 vUv;
        uniform sampler2D texture;
        uniform sampler2D texture2; 

        void main() {
           vec2 position =  vUv;
           if (vUv.x<aMin.x || vUv.x>aMax.x || vUv.y<aMin.y || vUv.y>aMax.y) {
                gl_FragColor = texture2D( texture2, position );
            } else {    
                position -= aMin;    
                position.x /= aMax.x - aMin.x;
                position.y /= aMax.y - aMin.y;    

                gl_FragColor = texture2D( texture, position );
            }            

        }
    </script>

http://jsfiddle.net/fj2r9b55/

我在 canvas 的不同位置绘制了多个图像,然后将 canvas 导出为 URL,我将其作为纹理 material 添加到网格:

  var scene = new THREE.Scene();
  var sceneWidth = window.innerWidth;
  var sceneHeight = window.innerHeight;
  var camera = new THREE.PerspectiveCamera(45, sceneWidth/sceneHeight, 0.1, 3000);
  var controls = new THREE.OrbitControls(camera);

  var raycaster = new THREE.Raycaster();
  var renderer = new THREE.WebGLRenderer({ alpha: true });
  renderer.setClearColor( 0xcccccc, 1);
  renderer.setSize(sceneWidth, sceneHeight);
  document.getElementById("content").appendChild(renderer.domElement);

  var canvas = document.createElement('canvas');
  canvas.width = 200;
  canvas.height = 900;

  var ctx = canvas.getContext("2d");

  var imgs = [];
  imgs.push(loadImage('http://uobot.com/demo/1.jpg', main));
  imgs.push(loadImage('http://uobot.com/demo/2.jpg', main));
  imgs.push(loadImage('http://uobot.com/demo/3.jpg', main));

  var imagesLoaded = 0;

  function main() {
     imagesLoaded ++;
     if(imagesLoaded == imgs.length) {
        for(var i in imgs) {
           ctx.drawImage(imgs[i], 0, i*100);
        }

        var dataUrl = canvas.toDataURL();

        var texture = THREE.ImageUtils.loadTexture(dataUrl);
        texture.needsUpdate = true;
        texture.minFilter = THREE.LinearFilter;
        var material = new THREE.MeshPhongMaterial( { 
           map: texture,
           specular: 0x050505,
           shininess: 0
        });
        var object = new THREE.Mesh(new THREE.PlaneGeometry(10, 60, 1, 1), material);
        scene.add(object);
     }
  }

  function loadImage(src, onload) {
     var img = new Image();

     img.onload = onload;
     img.src = src;

     return img;
  }