I'm working on a problem with three.js and ExtrudeGeometry.
I do have a wave-like structure which is made from several individual frames. Each of them is extruded using ExtrudeGeometry.
I'd like to apply a texture to each frame of the structure which is "wrapped around" the structure. For some reason (possibly wrong UV-mapping?) the texture does not display correctly on the extruded edges where the wave-like surface is out of level. (There are some tiny sections in the picture where the texture wraps correctly). I'm using the following script to apply the textures:
// create some simple Geometry
var shape = new THREE.Shape();
shape.moveTo( 0,0 );
shape.lineTo( 0,10 );
shape.lineTo( 100,7 );
shape.lineTo( 100,0 );
var extrudeSettings = {
steps: 2,
amount: 10,
bevelEnabled: false,
bevelThickness: 0,
bevelSize: 0,
bevelSegments: 0
};
var geometry = new THREE.ExtrudeGeometry( shape, extrudeSettings );
var texture = new THREE.Texture( image );
texture.wrapS = THREE.ClampToEdgeWrapping;
texture.wrapT = THREE.ClampToEdgeWrapping;
texture.repeat.set( 0.1, 0.1 );
var material = new THREE.MeshBasicMaterial( {map: texture} );
var mesh = new THREE.Mesh( geometry, material ) ;
scene.add( mesh );
Every help is much appreciated! Cheers!
Edit:
I've created this image to better illustrate the problem. White Arrows show, how the texture is supposed to wrap around the object. At some very rare spots it actually does!
Have a look at this example
https://threejs.org/examples/?q=geome#webgl_geometry_shapes
at row 70 there is a comment that states that texture.repeat must be set to (0.008, 0.008)
Related
Any help from this great community would be such a blesing. I've recently been trying to figure out how to plot a set of points and faces that come from an XML file with Three.js.
The points look something like this:
<P id="1">472227.25640192 2943287.51179465 200.138787</P>
<P id="2">472232.14363148 2943288.56768013 200.129142</P>
<P id="3">472237.03086105 2943289.62356560 200.119496</P>
and the faces look like this:
<F>1021 1020 1061</F>
<F>640 754 641</F>
<F>1534 1633 1535</F>
Keep in mind that there are thousands of these faces and points and each of them has 3 numbers. I've converted to xml to json and done all the parsing required but when I try to do a sample of some of the points as lines in Three.js, I get nothing but a black screen. Here's what I tried. Is anything like I'm trying to do even possible with three.js? Is there a better alternative?
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var camera = new THREE.PerspectiveCamera( 45, window.innerWidth / window.innerHeight, 1, 500 );
camera.position.set( 0, 0, 100 );
camera.lookAt( 0, 0, 0 );
var scene = new THREE.Scene();
var material = new THREE.LineBasicMaterial( { color: 0x0000ff } );
var geometry = new THREE.Geometry();
geometry.vertices.push(new THREE.Vector3( 472227.25640192, 2943287.51179465, 200.138787) );
geometry.vertices.push(new THREE.Vector3( 472232.14363148, 2943288.56768013, 200.129142) );
geometry.vertices.push(new THREE.Vector3( 472237.03086105, 2943289.62356560, 200.119496) );
var line = new THREE.Line( geometry, material );
scene.add( line );
renderer.render( scene, camera );
Thanks, any help is appreciated.
The vertices you define are putting the line outside of the viewport. For example, change the coords to
geometry.vertices.push(new THREE.Vector3(1, 2, 0));
geometry.vertices.push(new THREE.Vector3(3, 3, 0));
geometry.vertices.push(new THREE.Vector3(5, 6, 0));
and you will see the line.
-or-
If the values you're working with are as large as the ones in your example, move the camera waaaaaay back on the z axis. (you could also scale the values to something more manageable)
I need to reverse vertex order in faces of my geometry.
In example:
// create geometry
var geometry = new THREE.Geometry();
// create vertices
geometry.vertices.push( new THREE.Vector3( 0, 0, 0 ) );
geometry.vertices.push( new THREE.Vector3( 0, 100, 0 ) );
geometry.vertices.push( new THREE.Vector3( 100, 0, 0 ) );
// create face
var face = new THREE.Face3( 0, 1, 2 );
geometry.faces.push ( face );
// compute normals
geometry.computeFaceNormals();
geometry.computeVertexNormals();
// add to scene
var mesh = new THREE.Mesh(
geometry,
new THREE.MeshBasicMaterial({color: 0x00ffff})
);
scene.add( mesh );
Now I need to change order of vertices in face from 0,1,2 to 2,1,0. But when I do this manually it does not work no matter which flags for update I set to true.
The question - is it possible to reverse vertices order on the fly and if yes then how?
Important - It's better to avoid using negative scale for geometry in this case. And it's also better to avoid re-creating of object.
THREE.js: r73
delete mesh.geometry.__directGeometry;
This should apply yours changes. In some reason in r72 and r73 __directGeometry not updated automatically.
Drawing the sphere with mesh function.
function DRAW_SP(x,y,z)
{
var geometry = new THREE.SphereGeometry( .02, 100,100 );
var material = new THREE.MeshBasicMaterial( {color: 0xff0000} );
var sphere = new THREE.Mesh( geometry, material );
sphere.position.set(x,y,z );
scene.add( sphere );
}
its working good , but how to draw the same using Sphere.js, given in three.js/doc under math?
i tried like this
var sphere1= new THREE.Sphere(new THREE.Vector3( -l/2, 0, 0 ), 1.0);
scene.add( sphere1);
its not working .. can any one give a simple example to use like this?
sphere.js is the mathematically version of a sphere. It doesn't draw anything. It is used for calculations.
Is it possible to load multiple textures on a sphere?
I mean to say is there any way in Three.js to split a sphere into n pieces , texture them separately and render those pieces once again as a whole sphere?
I do not want to load the entire texture on the sphere, instead, only those parts are to be rendered which the user will first see on the screen and as the user rotates the sphere the rest part of the texture must be loaded.
Moreover, when I use a single image on a sphere it seems to converge at poles making it worse.
This should help: https://open.bekk.no/procedural-planet-in-webgl-and-three-js
Instead of using a sphere try using a cube and expanding it into a sphere. Cube logic on the cube sphere will save you a good amount of time.
var geometry = new THREE.BoxGeometry( 1, 1, 1, 8, 8, 8 );
for ( var i in geometry.vertices ) {
var vertex = geometry.vertices[ i ];
vertex.normalize().multiplyScalar(radius);
}
var materialArray = [];
var faceMaterial = new THREE.MeshLambertMaterial({
color: sphereColor,
transparent: true,
opacity: 0.4
});
for (var i = 0; i < 6; i++) {
materialArray.push(faceMaterial);
}
var material = new THREE.MeshFaceMaterial(materialArray);
var sphere = new THREE.Mesh( geometry, material );
scene.add( sphere );
I want to make parts of a mesh invisible at runtime. Can I set these parts invisible/transparent, e.g. by changing attributes of single faces? The mesh itself uses only one material.
Exemplary illustration as the editor understands this question: Imagine a mesh (here with a geometry of 20 vertices) where each quad of four vertices builds up a Face4. Now, some parts of the mesh should be made invisible (here two faces are invisible).
Note: This answer applies to legacy versions of three.js
You can assign a different material to each face. Here is an example where the faces share a material, but some faces are transparent:
// geometry
var geometry = new THREE.BoxGeometry( 100, 100, 100, 4, 4, 4 );
// materials
materials = [
new THREE.MeshLambertMaterial( { color: 0xffff00, side: THREE.DoubleSide } ),
new THREE.MeshBasicMaterial( { transparent: true, opacity: 0 } )
];
// assign material to each face
for( var i = 0; i < geometry.faces.length; i++ ) {
geometry.faces[ i ].materialIndex = THREE.Math.randInt( 0, 1 );
}
geometry.sortFacesByMaterialIndex(); // optional, to reduce draw calls
// mesh
mesh = new THREE.Mesh( geometry, materials );
scene.add( mesh );
three.js r.87