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

时间:2015-09-05 03:24:02

标签: three.js webgl

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

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

我遇到了与必须为纹理的每个部分创建新网格相关的性能问题,如果我可以通过某种方式将“贴花”放在单个网格上,那么整个过程就会运行得更顺畅。

2 个答案:

答案 0 :(得分:2)

您可以在自定义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/

答案 1 :(得分:0)

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

  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;
  }