How do you build a custom plane geometry in three.js?
Solution 1
Becare about PlaneGeometry, it is deprecated (so it will be removed in a next revision). Use PlaneBufferGeometry instead.
@pailhead's answer is correct if you want the 'normal' plane division.
If you want the vertices to have other positions you would have to build the geometry vertex per vertex that is something else*.
Also and that answers your need to move/animate the vertices later, you can change each vertex'position after the geometry creation by writing :
planeMesh.geometry.vertices[i].set(x,y,z);// this way you can move each vertex coordinates
planeMesh.geometry.verticesNeedUpdate=true;
* : example for a plane with 4 vertices (=2 triangles) :
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...
);
of course what makes this geometry a plane is that the 4 vertices are coplonar.
When you create a geometry with many faces, you understand you need a pen + paper to draw your faces :) Depending on your geometry you can also use an algorithm.
Solution 2
I created my customized plane, using:
// 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 );
Related videos on Youtube
blazerix
Updated on September 16, 2022Comments
-
blazerix over 1 year
I want to create a plane in three.js, but with more points than default (so I don't want to use PlaneGeometry, as I don't think it will let me define custom points). The reason being is that I want to be able to animate or move any given point in time.
This is what I have so far:
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(); }
What I'm looking to do, is create something like this:
http://www.math.ubc.ca/~cass/courses/m308-02b/projects/schweber/square%20tiles.gif
-
blazerix almost 9 yearsHow would you go about building it vertex by vertex?
-
blazerix almost 9 yearsSorry, ignore the above post (I'm still getting used to stackoverflow). So, I try the following:
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... );
but I get the an error: glDrawElements: attempt to access out of range vertices in attribute 1 -
Mouloud85 almost 9 yearsyou can delete your previous comment. You are asking me to debug code, please link a jsfiddle. You can upvote the answers you like by the way, and validate the one that brings most to you.
-
Mouloud85 almost 9 yearsI updated the fiddle with the last version of threejs and corrected the Face3(1,1,2) to (3,1,2). That was the cause of the error (you need 3 points for a face3...). However you still have work to do. I cannot do it for you, but you may will have to check those questions stackoverflow.com/questions/17640089/face-is-not-drawn, stackoverflow.com/questions/19085369/…
-
blazerix almost 9 yearsHi there, the problem is with the texture not displaying right?
-
blazerix almost 9 yearsHi Victor, Would it be possible to add a texture to your custom plane?
-
Víctor Romário Paz de Jesus almost 9 yearsYes. My customization was for a "ground" in my plan and it worked. here: 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; scene.add(ground);
-
Mouloud85 almost 9 yearsPlease don't make a conversation of commenting :) Just follow your way. You may encounter a problem that those links can answer
-
blazerix almost 9 yearsHi Victor, if it is okay with you, could you take a look at my JS Fiddle? All I see is a line across the screen. jsfiddle.net/z9z28ume
-
pailhead almost 9 yearsErrm, look at other examples in three.js (boxgeometry, cylindergeometry, spheregeometry) etc to get an idea on different primitives, topologies etc. The original question actually makes a call to the PlaneGeometry, and that class has only the UV subdivision available. Sure you can look into all sorts of algorithms to generate triangles or ngons in between, but i think you complicated things a bit.