如何在 three.js 中构建自定义平面几何图形?
How do you build a custom plane geometry in three.js?
我想在 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
尝试向 THREE.PlaneGeometry 添加两个参数。
THREE.PlaneGeometry(宽度、高度、宽度段、高度段)
查阅库(查看函数调用),查阅文档。
这也可能被使用:
http://threejs.org/docs/#Reference/Extras.Geometries/ParametricGeometry
注意 PlaneGeometry,它已被弃用(因此将在下一个修订版中删除)。请改用 PlaneBufferGeometry。
@pailhead 的答案是正确的,如果你想要 'normal' 平面分割。
如果您希望顶点有其他位置,则必须为每个顶点构建几何顶点,这是其他东西*。
此外,这满足了您稍后对 move/animate 顶点的需求,您可以在创建几何后更改每个顶点的位置,方法是编写:
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 个顶点共生。
当你创建一个有很多面的几何体时,你明白你需要笔+纸来画你的脸:) 根据你的几何体,你也可以使用算法。
我创建了我的定制飞机,使用:
// 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 );
如果你想添加一个带有自定义边框的平面,我建议你直接更改位置属性数组并更新几何点位置:
// 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
我想在 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
尝试向 THREE.PlaneGeometry 添加两个参数。
THREE.PlaneGeometry(宽度、高度、宽度段、高度段)
查阅库(查看函数调用),查阅文档。
这也可能被使用:
http://threejs.org/docs/#Reference/Extras.Geometries/ParametricGeometry
注意 PlaneGeometry,它已被弃用(因此将在下一个修订版中删除)。请改用 PlaneBufferGeometry。
@pailhead 的答案是正确的,如果你想要 'normal' 平面分割。
如果您希望顶点有其他位置,则必须为每个顶点构建几何顶点,这是其他东西*。
此外,这满足了您稍后对 move/animate 顶点的需求,您可以在创建几何后更改每个顶点的位置,方法是编写:
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 个顶点共生。
当你创建一个有很多面的几何体时,你明白你需要笔+纸来画你的脸:) 根据你的几何体,你也可以使用算法。
我创建了我的定制飞机,使用:
// 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 );
如果你想添加一个带有自定义边框的平面,我建议你直接更改位置属性数组并更新几何点位置:
// 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