javascript - (THREE.JS) 计算自定义缓冲区几何体的自定义 UV

标签 javascript three.js 3d texture-mapping indices

我正在尝试使用三个 JS 中的一些顶点数组创建曲线墙。 我将在数组中得到一些二维的基本顶点,它们将是墙的底部顶点。这些包括中心、下顶点和上顶点,这意味着它是两个面墙。基于这些顶点,我添加了一些墙的高度并将其 ​​2D 转换为 3D。
下面是代码和工作 fiddle

/**
 * Created by Singh on 7/30/2018.
 */

var renderer, scene, camera;

init();
animate();


function init() {
    wallsGeometry = function(totalPoints){


    var material = new THREE.MeshBasicMaterial({/*color: 0xff0000,*/ side: THREE.DoubleSide, wireframe : false});
    var material2 = new THREE.MeshBasicMaterial({/*color: 0x0044400, */side: THREE.DoubleSide, wireframe : true});

    var geometry = new THREE.BufferGeometry();
    var geometry2 = new THREE.BufferGeometry();

    var wallHeight = 200;


    var pointindices = [
        0,1,2,0,2,3,   //left

        5,4,7,5,7,6,   //right

        4,0,3,4,3,7,  //back

        1,5,6,1,6,2,    //front

        2,6,7,2,7,3,    //top

        5,1,0,5,0,4,  //bottom

    ];

    var pointindices2 = [
        1,0,2,1,3,2 , //left

        4,5,7,4,6,7,   //right

        0,4,3,0,7,3,  //back

        5,1,2,5,2,6,    //front

        6,2,7,6,3,7,    //top

        1,5,0,1,4,0,  //bottom

    ];

    var tempIndices = [];
    var tempIndices2 = [];


    for(var i=0; i<4; i++) {
        for (var j = 0; j < pointindices.length; j++) {
            tempIndices[pointindices.length * i + j] = 4 * i + pointindices[j];
        }
    }
    for(var i=0; i<4; i++) {
        for (var j = 0; j < pointindices2.length; j++) {
            tempIndices2[pointindices2.length * i + j] = 4 * i + pointindices2[j];
        }
    }


    var tempVerMesh = [];
    var tempVerMesh2 = [];

    var indices = new Uint32Array( tempIndices       );
    var pointsArray = { // for testing
        pointUpper1: new THREE.Vector3(),
        pointUpper2: new THREE.Vector3(),
        pointCenter1: new THREE.Vector3(),
        pointCenter2: new THREE.Vector3(),
        pointLower1: new THREE.Vector3(),
        pointLower2: new THREE.Vector3()
    };

console.log(totalPoints);
    /*function generateUVs(geometry) {
        geometry.computeBoundingBox();

        var max = geometry.boundingBox.max, min = geometry.boundingBox.min;

        var offset = new THREE.Vector3(0 - min.x, 0 - min.y);
        var range = new THREE.Vector3(max.x - min.x, max.y - min.y);
        var faces = geometry.faces;

        geometry.faceVertexUvs[0] = [];

        for (var i = 0; i < faces.length ; i++) {

            var v1 = geometry.vertices[faces[i].a],
                v2 = geometry.vertices[faces[i].b],
                v3 = geometry.vertices[faces[i].c];

            geometry.faceVertexUvs[0].push([
                new THREE.Vector3((v1.x + offset.x)/range.x ,(v1.y + offset.y)/range.y),
                new THREE.Vector3((v2.x + offset.x)/range.x ,(v2.y + offset.y)/range.y),
                new THREE.Vector3((v3.x + offset.x)/range.x ,(v3.y + offset.y)/range.y),
            ]);
        }
        geometry.uvsNeedUpdate = true;
        return geometry;
    }*/
        for (var i = 0; i < totalPoints.lower.length    ; i++) {
            pointsArray.pointCenter1 = totalPoints.center[i];
            //pointsArray.pointCenter2 = totalPoints.center[i + 1];
            pointsArray.pointLower1 = totalPoints.lower[i];
            //pointsArray.pointLower2 = totalPoints.lower[i + 1];
            pointsArray.pointUpper1 = totalPoints.upper[i];
            //pointsArray.pointUpper2 = totalPoints.upper[i + 1];
            tempVerMesh.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y, pointsArray.pointCenter1.z);
            tempVerMesh.push(pointsArray.pointLower1.x, pointsArray.pointLower1.y, pointsArray.pointLower1.z);
            tempVerMesh.push(pointsArray.pointLower1.x, pointsArray.pointLower1.y + wallHeight, pointsArray.pointLower1.z);
            tempVerMesh.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y + wallHeight, pointsArray.pointCenter1.z);



            tempVerMesh2.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y, pointsArray.pointCenter1.z);
            tempVerMesh2.push(pointsArray.pointUpper1.x, pointsArray.pointUpper1.y, pointsArray.pointUpper1.z);

            tempVerMesh2.push(pointsArray.pointUpper1.x, pointsArray.pointUpper1.y + wallHeight, pointsArray.pointUpper1.z );
            tempVerMesh2.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y + wallHeight, pointsArray.pointCenter1.z);

        }


    var vertices = new Float32Array(tempVerMesh);
    var vertices2 = new Float32Array(tempVerMesh2);

    //var uvs = new Float32Array(pointUVs);

            geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
            geometry.setIndex(new THREE.BufferAttribute(indices, 1));
            //geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2));

            geometry.computeFaceNormals();
            geometry.computeVertexNormals();
    console.log(geometry);

            var mesh = new THREE.Mesh(geometry, material);



    var indices2 = new Uint32Array(tempIndices2);
    geometry2.addAttribute('position', new THREE.BufferAttribute(vertices2, 3));
    geometry2.setIndex(new THREE.BufferAttribute(indices2, 1));



    geometry2.computeFaceNormals();
    geometry2.computeVertexNormals();

   /*var geom = new THREE.Geometry().fromBufferGeometry(geometry2);
    var temp = generateUVs(geom);
    geometry2 = new THREE.BufferGeometry().fromGeometry(temp);*/
    var mesh2 = new THREE.Mesh(geometry2, material2);


    //geometry2.addAttribute('uv', new THREE.BufferAttribute(uvs2, 2));


    return [mesh,mesh2];

};

  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
camera.position.z = 400;

scene = new THREE.Scene();

var arrow;
var rayCaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();

renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );

renderer.domElement.addEventListener("mousemove", onMouseMove);

var points = {
    pointUpper1: new THREE.Vector3(-70, 0, -20),
    pointUpper2: new THREE.Vector3(130, 0, -20),
    pointCenter1: new THREE.Vector3(-100, 0, 0),
    pointCenter2: new THREE.Vector3(150, 0, 0),
    pointLower1: new THREE.Vector3(-70, 0, 20),
    pointLower2: new THREE.Vector3(130, 0, 20)
};

var totalPoints = {
    center : [new THREE.Vector3(-70, 0, 0),new THREE.Vector3(0, 0, 0),new THREE.Vector3(50, 0, 0),new THREE.Vector3(100, 0, 0),new THREE.Vector3(130, 0, 0)],
    lower : [new THREE.Vector3(-70, 0, 20),new THREE.Vector3(0, 0, 20),new THREE.Vector3(50, 0, 20),new THREE.Vector3(100, 0, 20),new THREE.Vector3(130, 0, 20)],
    upper : [new THREE.Vector3(-70, 0, -20),new THREE.Vector3(0, 0, -20),new THREE.Vector3(50, 0, -20),new THREE.Vector3(100, 0, -20),new THREE.Vector3(130, 0, -20)]
};

var sphere = new THREE.SphereGeometry(2, 10, 10);

function initPoints(){
    var point1mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: 0xff00}));
    point1mesh.position.copy(points.pointUpper1);
    scene.add(point1mesh);

    var point2mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: 0x0000ff}));
    point2mesh.position.copy(points.pointUpper2);
    scene.add(point2mesh);

    var point3mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: 0xff00}));
    point3mesh.position.copy(points.pointCenter1);
    scene.add(point3mesh);

    var point4mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: 0x0000ff}));
    point4mesh.position.copy(points.pointCenter2);
    scene.add(point4mesh);

    var point5mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: 0xff00}));
    point5mesh.position.copy(points.pointLower1);
    scene.add(point5mesh);

    var point6mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({color: 0x0000ff}));
    point6mesh.position.copy(points.pointLower2);
    scene.add(point6mesh);
}
 initPoints();

    var mesh = new wallsGeometry(totalPoints);



function createArrow() {
    var length = 30;
    arrow = new THREE.ArrowHelper(
        THREE.Object3D.DefaultUp,
        new THREE.Vector3(),
        length,
        0xffff00,
        1.5 * length,
        1.25 * length
    );
    arrow.position.z = 10;
    scene.add(arrow);
}
// arrow
createArrow();

function updateArrow(object, point, face) {
    arrow.position.copy(point);
    var normalMatrix = new THREE.Matrix3().getNormalMatrix( object.matrixWorld );
    var normal = face.normal.clone().applyMatrix3( normalMatrix ).normalize();
    arrow.setDirection(normal);
}

function onMouseMove(event) {
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    rayCaster.setFromCamera(mouse, camera);

    var intersects = rayCaster.intersectObject(mesh[0], true);
    var i, il, intersect;
    if (intersects[0]) {
        var face = intersects[0].face;
        var point = intersects[0].point;
        var object = intersects[0].object;
        updateArrow(object, point, face);
    }
}
/*         var textureLoader = new THREE.TextureLoader();
    textureLoader.load('./textures/Capture.PNG', function (texture) {
        console.log('texture loaded');
        texture.minFilter = THREE.LinearFilter;

        //mesh[0].material.map = texture;
        var vertexNormalsHelper = new THREE.VertexNormalsHelper( mesh[0], 10 );
        mesh[0].add( vertexNormalsHelper );
    }); */
        scene.add(mesh[0]);

 /*     textureLoader.load('./textures/abc.jpg', function (texture) {
    console.log('texture loaded');
    texture.minFilter = THREE.LinearFilter;
    //mesh[1].material.map = texture;
    var vertexNormalsHelper = new THREE.VertexNormalsHelper( mesh[1], 10 );
    mesh[1].add( vertexNormalsHelper );
}); */
        scene.add(mesh[1]);

//
var Orbitcontrols = new THREE.OrbitControls(camera,renderer.domElement);
Orbitcontrols.update();

}

// render
function render() {
    renderer.render(scene, camera);
}

// animate
function animate() {
    requestAnimationFrame(animate);
    render();
}

https://jsfiddle.net/simar_aneja/fsmw8znq/6/

在 fiddle 中,您可以看到墙正在正确构建,您可以在开始时增加创建这些索引的顶点和循环。现在我想将UV添加到这个bufferGeometry中,我尝试转换为几何体,然后计算faceVertexUVs,但这不是正确的方法。谁能建议我进一步的路径,我可以仅在正面附加不同的纹理,在顶部附加不同的纹理。并且应该是这样的,无论有多少个顶点,Uvs都应该根据顶点的长度来计算。我有一些想法,但不知道如何使其在墙壁的不同侧面有所不同。

谢谢

最佳答案

这是我为你准备的 UV 盒子拆开包装。也许你会发现它很有帮助...

我还将您的 fiddle 放入您可以在下面运行的代码片段中...

function boxUnwrapUVs(geometry) {
  if (!geometry.boundingBox) geometry.computeBoundingBox();
  var sz = geometry.boundingBox.getSize(new THREE.Vector3());
  var center = geometry.boundingBox.getCenter(new THREE.Vector3())
  var min = geometry.boundingBox.min;
  if (geometry.faceVertexUvs[0].length == 0) {
    for (var i = 0; i < geometry.faces.length; i++) {
      geometry.faceVertexUvs[0].push([new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2()]);
    }
  }
  for (var i = 0; i < geometry.faces.length; i++) {
    var face = geometry.faces[i];
    var faceUVs = geometry.faceVertexUvs[0][i]
    var va = geometry.vertices[geometry.faces[i].a]
    var vb = geometry.vertices[geometry.faces[i].b]
    var vc = geometry.vertices[geometry.faces[i].c]
    var vab = new THREE.Vector3().copy(vb).sub(va)
    var vac = new THREE.Vector3().copy(vc).sub(va)
    //now we have 2 vectors to get the cross product of...
    var vcross = new THREE.Vector3().copy(vab).cross(vac);
    //Find the largest axis of the plane normal...
    vcross.set(Math.abs(vcross.x), Math.abs(vcross.y), Math.abs(vcross.z))
    var majorAxis = vcross.x > vcross.y ? (vcross.x > vcross.z ? 'x' : vcross.y > vcross.z ? 'y' : vcross.y > vcross.z) : vcross.y > vcross.z ? 'y' : 'z'
    //Take the other two axis from the largest axis
    var uAxis = majorAxis == 'x' ? 'y' : majorAxis == 'y' ? 'x' : 'x';
    var vAxis = majorAxis == 'x' ? 'z' : majorAxis == 'y' ? 'z' : 'y';
    faceUVs[0].set((va[uAxis] - min[uAxis]) / sz[uAxis], (va[vAxis] - min[vAxis]) / sz[vAxis])
    faceUVs[1].set((vb[uAxis] - min[uAxis]) / sz[uAxis], (vb[vAxis] - min[vAxis]) / sz[vAxis])
    faceUVs[2].set((vc[uAxis] - min[uAxis]) / sz[uAxis], (vc[vAxis] - min[vAxis]) / sz[vAxis])
  }
  geometry.elementsNeedUpdate = geometry.verticesNeedUpdate = true;
}
geometry = new THREE.Geometry().fromBufferGeometry(geometry)
boxUnwrapUVs(geometry)
var mesh = new THREE.Mesh(geometry, material);

/**
 * Created by Singh on 7/30/2018.
 */

var renderer, scene, camera;

init();
animate();


function init() {
  wallsGeometry = function(totalPoints) {

    var rrnd = (min, max) => (Math.random() * (max - min)) + min
    var irnd = (rng) => (Math.random() * rng) | 0

    function makeRndCanvas() {
      var canvas = document.createElement('canvas');
      canvas.width = canvas.height = 128;
      var ctx = canvas.getContext('2d');
      var srnd = (rng) => (Math.random() - 0.5) * 2 * rng
      var irnd = (rng) => ((Math.random() * rng) | 0)
      for (var x = 0; x < canvas.width; x++) {
        for (var y = 0; y < canvas.width; y++) {
          ctx.fillStyle = `rgba(${irnd(256)},${irnd(256)},${irnd(256)},1.0)`
          ctx.fillRect(x, y, 1, 1);
        }
      }
      ctx.fillStyle = '#ffff00'
      ctx.fillText("WAHOO", 3, 64)
      return canvas;
    }


    function makeRndTexture() {
      var tex = new THREE.Texture(makeRndCanvas())
      tex.minFilter = // THREE.LinearMipMapLinearFilter;
        tex.magFilter = THREE.NearestFilter; //THREE.LinearFilter;

      tex.wrapS = tex.wrapT = THREE.RepeatWrapping;
      //tex.repeat.set(0.01, 0.01);
      tex.needsUpdate = true;
      return tex;
    }

    var material = new THREE.MeshLambertMaterial({ /*color: 0xff0000,*/
      side: THREE.DoubleSide,
      wireframe: false,
      map: makeRndTexture()
    });
    var material2 = new THREE.MeshLambertMaterial({ /*color: 0x0044400, */
      side: THREE.DoubleSide,
      wireframe: true
    });

    var geometry = new THREE.BufferGeometry();
    var geometry2 = new THREE.BufferGeometry();

    var wallHeight = 200;


    var pointindices = [
      0, 1, 2, 0, 2, 3, //left

      5, 4, 7, 5, 7, 6, //right

      4, 0, 3, 4, 3, 7, //back

      1, 5, 6, 1, 6, 2, //front

      2, 6, 7, 2, 7, 3, //top

      5, 1, 0, 5, 0, 4, //bottom

    ];

    var pointindices2 = [
      1, 0, 2, 1, 3, 2, //left

      4, 5, 7, 4, 6, 7, //right

      0, 4, 3, 0, 7, 3, //back

      5, 1, 2, 5, 2, 6, //front

      6, 2, 7, 6, 3, 7, //top

      1, 5, 0, 1, 4, 0, //bottom

    ];

    var tempIndices = [];
    var tempIndices2 = [];


    for (var i = 0; i < 4; i++) {
      for (var j = 0; j < pointindices.length; j++) {
        tempIndices[pointindices.length * i + j] = 4 * i + pointindices[j];
      }
    }
    for (var i = 0; i < 4; i++) {
      for (var j = 0; j < pointindices2.length; j++) {
        tempIndices2[pointindices2.length * i + j] = 4 * i + pointindices2[j];
      }
    }


    var tempVerMesh = [];
    var tempVerMesh2 = [];

    var indices = new Uint32Array(tempIndices);
    var pointsArray = { // for testing
      pointUpper1: new THREE.Vector3(),
      pointUpper2: new THREE.Vector3(),
      pointCenter1: new THREE.Vector3(),
      pointCenter2: new THREE.Vector3(),
      pointLower1: new THREE.Vector3(),
      pointLower2: new THREE.Vector3()
    };

    console.log(totalPoints);
    /*function generateUVs(geometry) {
        geometry.computeBoundingBox();

        var max = geometry.boundingBox.max, min = geometry.boundingBox.min;

        var offset = new THREE.Vector3(0 - min.x, 0 - min.y);
        var range = new THREE.Vector3(max.x - min.x, max.y - min.y);
        var faces = geometry.faces;

        geometry.faceVertexUvs[0] = [];

        for (var i = 0; i < faces.length ; i++) {

            var v1 = geometry.vertices[faces[i].a],
                v2 = geometry.vertices[faces[i].b],
                v3 = geometry.vertices[faces[i].c];

            geometry.faceVertexUvs[0].push([
                new THREE.Vector3((v1.x + offset.x)/range.x ,(v1.y + offset.y)/range.y),
                new THREE.Vector3((v2.x + offset.x)/range.x ,(v2.y + offset.y)/range.y),
                new THREE.Vector3((v3.x + offset.x)/range.x ,(v3.y + offset.y)/range.y),
            ]);
        }
        geometry.uvsNeedUpdate = true;
        return geometry;
    }*/
    for (var i = 0; i < totalPoints.lower.length; i++) {
      pointsArray.pointCenter1 = totalPoints.center[i];
      //pointsArray.pointCenter2 = totalPoints.center[i + 1];
      pointsArray.pointLower1 = totalPoints.lower[i];
      //pointsArray.pointLower2 = totalPoints.lower[i + 1];
      pointsArray.pointUpper1 = totalPoints.upper[i];
      //pointsArray.pointUpper2 = totalPoints.upper[i + 1];
      tempVerMesh.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y, pointsArray.pointCenter1.z);
      tempVerMesh.push(pointsArray.pointLower1.x, pointsArray.pointLower1.y, pointsArray.pointLower1.z);
      tempVerMesh.push(pointsArray.pointLower1.x, pointsArray.pointLower1.y + wallHeight, pointsArray.pointLower1.z);
      tempVerMesh.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y + wallHeight, pointsArray.pointCenter1.z);



      tempVerMesh2.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y, pointsArray.pointCenter1.z);
      tempVerMesh2.push(pointsArray.pointUpper1.x, pointsArray.pointUpper1.y, pointsArray.pointUpper1.z);

      tempVerMesh2.push(pointsArray.pointUpper1.x, pointsArray.pointUpper1.y + wallHeight, pointsArray.pointUpper1.z);
      tempVerMesh2.push(pointsArray.pointCenter1.x, pointsArray.pointCenter1.y + wallHeight, pointsArray.pointCenter1.z);

    }


    var vertices = new Float32Array(tempVerMesh);
    var vertices2 = new Float32Array(tempVerMesh2);

    //var uvs = new Float32Array(pointUVs);

    geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
    geometry.setIndex(new THREE.BufferAttribute(indices, 1));
    //geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2));

    geometry.computeFaceNormals();
    geometry.computeVertexNormals();
    console.log(geometry);

    function boxUnwrapUVs(geometry) {
      if (!geometry.boundingBox) geometry.computeBoundingBox();
      var sz = geometry.boundingBox.getSize(new THREE.Vector3());
      var center = geometry.boundingBox.getCenter(new THREE.Vector3())
      var min = geometry.boundingBox.min;
      if (geometry.faceVertexUvs[0].length == 0) {
        for (var i = 0; i < geometry.faces.length; i++) {
          geometry.faceVertexUvs[0].push([new THREE.Vector2(), new THREE.Vector2(), new THREE.Vector2()]);
        }
      }
      for (var i = 0; i < geometry.faces.length; i++) {
        var face = geometry.faces[i];
        var faceUVs = geometry.faceVertexUvs[0][i]
        var va = geometry.vertices[geometry.faces[i].a]
        var vb = geometry.vertices[geometry.faces[i].b]
        var vc = geometry.vertices[geometry.faces[i].c]
        var vab = new THREE.Vector3().copy(vb).sub(va)
        var vac = new THREE.Vector3().copy(vc).sub(va)
        //now we have 2 vectors to get the cross product of...
        var vcross = new THREE.Vector3().copy(vab).cross(vac);
        //Find the largest axis of the plane normal...
        vcross.set(Math.abs(vcross.x), Math.abs(vcross.y), Math.abs(vcross.z))
        var majorAxis = vcross.x > vcross.y ? (vcross.x > vcross.z ? 'x' : vcross.y > vcross.z ? 'y' : vcross.y > vcross.z) : vcross.y > vcross.z ? 'y' : 'z'
        //Take the other two axis from the largest axis
        var uAxis = majorAxis == 'x' ? 'y' : majorAxis == 'y' ? 'x' : 'x';
        var vAxis = majorAxis == 'x' ? 'z' : majorAxis == 'y' ? 'z' : 'y';
        faceUVs[0].set((va[uAxis] - min[uAxis]) / sz[uAxis], (va[vAxis] - min[vAxis]) / sz[vAxis])
        faceUVs[1].set((vb[uAxis] - min[uAxis]) / sz[uAxis], (vb[vAxis] - min[vAxis]) / sz[vAxis])
        faceUVs[2].set((vc[uAxis] - min[uAxis]) / sz[uAxis], (vc[vAxis] - min[vAxis]) / sz[vAxis])
      }
      geometry.elementsNeedUpdate = geometry.verticesNeedUpdate = true;
    }
    geometry = new THREE.Geometry().fromBufferGeometry(geometry)
    boxUnwrapUVs(geometry)
    geometry = new THREE.BufferGeometry().fromGeometry(geometry)
    var mesh = new THREE.Mesh(geometry, material);






    var indices2 = new Uint32Array(tempIndices2);
    geometry2.addAttribute('position', new THREE.BufferAttribute(vertices2, 3));
    geometry2.setIndex(new THREE.BufferAttribute(indices2, 1));



    geometry2.computeFaceNormals();
    geometry2.computeVertexNormals();

    /*      var geom = new THREE.Geometry().fromBufferGeometry(geometry2);
            var temp = generateUVs(geom);
            geometry2 = new THREE.BufferGeometry().fromGeometry(temp);*/
    var mesh2 = new THREE.Mesh(geometry2, material2);


    //geometry2.addAttribute('uv', new THREE.BufferAttribute(uvs2, 2));


    return [mesh, mesh2];

  };

  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 10000);
  camera.position.z = 400;

  scene = new THREE.Scene();

  var arrow;
  var rayCaster = new THREE.Raycaster();
  var mouse = new THREE.Vector2();

  renderer = new THREE.WebGLRenderer();
  renderer.setSize(window.innerWidth, window.innerHeight);

  var light = new THREE.DirectionalLight();
  light.position.set(200, 200, 200)
  scene.add(light)
  document.body.appendChild(renderer.domElement);

  renderer.domElement.addEventListener("mousemove", onMouseMove);

  var points = {
    pointUpper1: new THREE.Vector3(-70, 0, -20),
    pointUpper2: new THREE.Vector3(130, 0, -20),
    pointCenter1: new THREE.Vector3(-100, 0, 0),
    pointCenter2: new THREE.Vector3(150, 0, 0),
    pointLower1: new THREE.Vector3(-70, 0, 20),
    pointLower2: new THREE.Vector3(130, 0, 20)
  };

  var totalPoints = {
    center: [new THREE.Vector3(-70, 0, 0), new THREE.Vector3(0, 0, 0), new THREE.Vector3(50, 0, 0), new THREE.Vector3(100, 0, 0), new THREE.Vector3(130, 0, 0)],
    lower: [new THREE.Vector3(-70, 0, 20), new THREE.Vector3(0, 0, 20), new THREE.Vector3(50, 0, 20), new THREE.Vector3(100, 0, 20), new THREE.Vector3(130, 0, 20)],
    upper: [new THREE.Vector3(-70, 0, -20), new THREE.Vector3(0, 0, -20), new THREE.Vector3(50, 0, -20), new THREE.Vector3(100, 0, -20), new THREE.Vector3(130, 0, -20)]
  };

  var sphere = new THREE.SphereGeometry(2, 10, 10);

  function initPoints() {
    var point1mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
      color: 0xff00
    }));
    point1mesh.position.copy(points.pointUpper1);
    scene.add(point1mesh);

    var point2mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
      color: 0x0000ff
    }));
    point2mesh.position.copy(points.pointUpper2);
    scene.add(point2mesh);

    var point3mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
      color: 0xff00
    }));
    point3mesh.position.copy(points.pointCenter1);
    scene.add(point3mesh);

    var point4mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
      color: 0x0000ff
    }));
    point4mesh.position.copy(points.pointCenter2);
    scene.add(point4mesh);

    var point5mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
      color: 0xff00
    }));
    point5mesh.position.copy(points.pointLower1);
    scene.add(point5mesh);

    var point6mesh = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({
      color: 0x0000ff
    }));
    point6mesh.position.copy(points.pointLower2);
    scene.add(point6mesh);
  }
  initPoints();

  var mesh = new wallsGeometry(totalPoints);


  function createArrow() {
    var length = 30;
    arrow = new THREE.ArrowHelper(
      THREE.Object3D.DefaultUp,
      new THREE.Vector3(),
      length,
      0xffff00,
      1.5 * length,
      1.25 * length
    );
    arrow.position.z = 10;
    scene.add(arrow);
  }
  // arrow
  createArrow();

  function updateArrow(object, point, face) {
    arrow.position.copy(point);
    var normalMatrix = new THREE.Matrix3().getNormalMatrix(object.matrixWorld);
    var normal = face.normal.clone().applyMatrix3(normalMatrix).normalize();
    arrow.setDirection(normal);
  }

  function onMouseMove(event) {
    mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
    mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
    rayCaster.setFromCamera(mouse, camera);

    var intersects = rayCaster.intersectObject(mesh[0], true);
    var i, il, intersect;
    if (intersects[0]) {
      var face = intersects[0].face;
      var point = intersects[0].point;
      var object = intersects[0].object;
      updateArrow(object, point, face);
    }
  }
  /*         var textureLoader = new THREE.TextureLoader();
      textureLoader.load('./textures/Capture.PNG', function (texture) {
          console.log('texture loaded');
          texture.minFilter = THREE.LinearFilter;
      
          //mesh[0].material.map = texture;
          var vertexNormalsHelper = new THREE.VertexNormalsHelper( mesh[0], 10 );
          mesh[0].add( vertexNormalsHelper );
      }); */
  scene.add(mesh[0]);

  /*     textureLoader.load('./textures/abc.jpg', function (texture) {
      console.log('texture loaded');
      texture.minFilter = THREE.LinearFilter;
      //mesh[1].material.map = texture;
      var vertexNormalsHelper = new THREE.VertexNormalsHelper( mesh[1], 10 );
      mesh[1].add( vertexNormalsHelper );
  }); */
  scene.add(mesh[1]);

  //
  var Orbitcontrols = new THREE.OrbitControls(camera, renderer.domElement);
  Orbitcontrols.update();

}

// render
function render() {
  renderer.render(scene, camera);
}

// animate
function animate() {
  requestAnimationFrame(animate);
  render();
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src="https://cdn.rawgit.com/mrdoob/three.js/master/examples/js/controls/OrbitControls.js"></script>

关于javascript - (THREE.JS) 计算自定义缓冲区几何体的自定义 UV,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51659109/

相关文章:

javascript - 为什么会出现这样的结果?

javascript - Three.js 中的基本 Collada 加载

c++ - 在Qt3D中进行碰撞检测的预期方法(或好方法)是什么?

c# - 绘制立方体的无 Glu 示例?

java - 尝试用 Java 将 2D 图像转换为 3D 对象

javascript - 检查 n 个元素是否包含设置为 true 的 data 属性

javascript - 获取元素值并添加它们(parseFloat 似乎失败)

javascript - 这是有效的 xpath 查询吗?

javascript - 将圆柱体转换为弯管

python - 将 FBX 转换为 three.js