【问题标题】:How do you build a custom plane geometry in three.js?如何在 three.js 中构建自定义平面几何?
【发布时间】:2015-09-26 15:40:00
【问题描述】:

我想在 three.js 中创建一个平面,但点比默认点多(所以我不想使用 PlaneGeometry,因为我认为它不会让我定义自定义点)。原因是我希望能够动画或移动任何给定的时间点。

这是我目前所拥有的:

var camera;
var scene;
var renderer;
var mesh;

init();
animate();

function init() {

    scene = new THREE.Scene();
    camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 1000);

    var light = new THREE.DirectionalLight( 0xffffff );
    light.position.set( 0, 1, 1 ).normalize();
    scene.add(light);


    var geometry = new THREE.PlaneGeometry( 50, 50);  

    var texture = THREE.ImageUtils.loadTexture('images/03032122.png', {}, function() {
    renderer.render(scene, camera);
    })
    var material = new THREE.MeshBasicMaterial({map: texture, transparent: true })


    mesh = new THREE.Mesh(geometry, material );
    mesh.position.z = -50;
    scene.add( mesh );

    renderer = new THREE.WebGLRenderer({ alpha: true });
    renderer.setSize( window.innerWidth, window.innerHeight );

    renderer.setClearColor( 0xffffff, 1);
    document.body.appendChild( renderer.domElement );

    window.addEventListener( 'resize', onWindowResize, false );

    render();
}

function animate() {
    //mesh.scale.x+= 0.0003;


    render();
    requestAnimationFrame( animate );

}

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


function onWindowResize() {
    camera.aspect = window.innerWidth / window.innerHeight;
    camera.updateProjectionMatrix();
    renderer.setSize( window.innerWidth, window.innerHeight );
    render();
}

我想做的是创建这样的东西:

http://www.math.ubc.ca/~cass/courses/m308-02b/projects/schweber/square%20tiles.gif

【问题讨论】:

    标签: javascript 3d three.js polygon


    【解决方案1】:

    尝试向 THREE.PlaneGeometry 添加另外两个参数。

    THREE.PlaneGeometry( 宽度 , 高度 , widthSegments , heightSegments )

    查阅库(查看函数调用),查阅文档。

    这也可能被使用:

    http://threejs.org/docs/#Reference/Extras.Geometries/ParametricGeometry

    【讨论】:

      【解决方案2】:

      注意 PlaneGeometry,它已被弃用(因此它将在下一个版本中删除)。请改用 PlaneBufferGeometry。

      如果您想要“正常”平面划分,@pailhead 的答案是正确的。

      如果您希望顶点具有其他位置,则必须为每个顶点构建几何顶点,这是其他东西*。

      这也满足了您稍后移动/动画顶点的需要,您可以在创建几何图形后更改每个顶点的位置:

      planeMesh.geometry.vertices[i].set(x,y,z);// this way you can move each vertex coordinates
      planeMesh.geometry.verticesNeedUpdate=true;
      

      * : 具有 4 个顶点(=2 个三角形)的平面示例:

      var geo=new THREE.Geometry();
      geometry.vertices.push(
          new THREE.Vector3(x1,y1,z1),//vertex0
          new THREE.Vector3(x2,y2,z2),//1
          new THREE.Vector3(x3,y3,z3),//2
          new THREE.Vector3(x4,y4,z4)//3
          );
      geometry.faces.push(
          new THREE.Face3(2,1,0),//use vertices of rank 2,1,0
          new THREE.Face3(3,1,2)//vertices[3],1,2...
          );
      

      当然,使这个几何图形成为平面的原因是 4 个顶点是共轴的。

      当您创建具有许多面的几何图形时,您会明白需要笔和纸来绘制您的面 :) 根据您的几何图形,您还可以使用算法。

      【讨论】:

      • 你将如何逐个顶点地构建它?
      • 对不起,忽略上面的帖子(我还在习惯stackoverflow)。因此,我尝试以下操作:geometry.vertices.push( new THREE.Vector3(0,1,10),//vertex0 new THREE.Vector3(1,0,10),//1 new THREE.Vector3(1,1,10),//2 new THREE.Vector3(0,0,10)//3 ); geometry.faces.push( new THREE.Face3(2,1,0),//use vertices of rank 2,1,0 new THREE.Face3(1,1,2)//vertices[3],1,2... ); 但我收到错误:glDrawElements:尝试访问属性 1 中超出范围的顶点
      • 您可以删除之前的评论。您要我调试代码,请链接一个 jsfiddle。您可以顺便给您喜欢的答案投票,并验证给您带来最多的答案。
      • 我用最后一个版本的threejs更新了fiddle,并将Face3(1,1,2)更正为(3,1,2)。这就是错误的原因(你需要 3 分来获得一个 face3 ...)。但是,您还有工作要做。我不能为你做,但你可能需要检查这些问题stackoverflow.com/questions/17640089/face-is-not-drawnstackoverflow.com/questions/19085369/…
      • 您好,问题是纹理显示不正确?
      【解决方案3】:

      我创建了我的定制飞机,使用:

              // Plane
                  var size = 500, step = 100;
                  var geometry = new THREE.Geometry();
                  for ( var i = - size; i <= size; i += step ) {
      
                      geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
                      geometry.vertices.push( new THREE.Vector3(   size, 0, i ) );
      
                      geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
                      geometry.vertices.push( new THREE.Vector3( i, 0,   size ) );
      
                  }
      
                  var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.5 } );
      
                  var line = new THREE.Line( geometry, material, THREE.LinePieces );
                  scene.add( line );
      

      【讨论】:

      • 嗨,维克多,可以为您的自定义飞机添加纹理吗?
      • 是的。我的定制是为我的计划中的“基础”而设计的,它奏效了。这里:var ground = new THREE.Mesh(new THREE.PlaneGeometry(1000, 1000, 50, 50), new THREE.MeshLambertMaterial({color:0xFFFFFF})); ground.receiveShadow = true; ground.position.set(0, -25, 0); ground.rotation.x = -Math.PI / 2;场景.add(ground);
      • 嗨,维克多,如果你没问题,你能看看我的 JS Fiddle 吗?我所看到的只是屏幕上的一条线。 jsfiddle.net/z9z28ume
      【解决方案4】:

      如果你想添加一个带有自定义边框的平面,我建议你直接更改位置属性数组并更新几何点位置:

      // Here you chose the divisions in x
          const x_lenght = 1 
          const divisions = 10
          
          let geometry = new THREE.PlaneBufferGeometry( x_lenght, 1, divisions, 1 )
          let material = new THREE.MeshPhongMaterial( { color: 0xecf0f1, wireframe: true } )
          
          let pointPos = geometry.getAttribute("position").array
              
          for (let i = 0; i < divisions + 1; i++) {
            let x = pointPos[3 * i] + x_lenght/2
      
            // This case is making y = x^2
            pointPos[3 * i + 1] = Math.pow(x, 2) 
            pointPos[3 * ( divisions + 1 ) + 3 * i + 1] = - pointPos[3 * i  + 1]
            
            console.log(`x = ${pointPos[3 * i]}; y = ${pointPos[3 * ( divisions + 1 ) + 3 * i + 1]}`)
      
              }
          
          pointPos.needsUpdate = true;
          
          mesh = new THREE.Mesh(geometry, material )
      
          scene.add(mesh)
      
      

      这是我的例子https://codepen.io/ferrari212/pen/bGpgLBd?editors=0010

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-05-16
        • 1970-01-01
        • 1970-01-01
        • 2015-01-19
        • 2016-04-28
        • 2013-04-06
        相关资源
        最近更新 更多