three.js - apply different material to extruded shape - three.js

I have Three.Shape which I can apply Extrusion
To get a plane I drew a square first and then apply extrusion
var squareShape = new THREE.Shape();
squareShape.moveTo( 0,0 );
squareShape.lineTo( 0, sqLength );
squareShape.lineTo( sqLength, sqLength );
squareShape.lineTo( sqLength, 0 );
squareShape.lineTo( 0, 0 );
var geometry = new THREE.ExtrudeGeometry( squareShape,extrudeSettings);
now a 3D square is appearing on my browser.
Next I want to apply a image texture of 256x256 on its top face. How to do this?

If you look at src/extras/geometries/ExtrudeGeometry.js in THREE.js you will see these comments.
material: // material index for front and back faces
extrudeMaterial: // material index for extrusion and beveled faces
So for example you can say (obviously won't run directly because it is incomplete)
// The face material will be index #0. The extrusion (sides) will be #1.
var extrudeSettings = { amount: 10, bevelEnabled: true, bevelSegments: 3, steps: 4, bevelThickness: 8, material: 0, extrudeMaterial: 1 };
And when you create your mesh you create 2 materials and assign them to your mesh.
var mesh = THREE.SceneUtils.createMultiMaterialObject( geometry, [ new THREE.MeshLambertMaterial( { color: color } ), new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, transparent: true } ) ] );
Hope this gets you on the right path.
On a side note, related to the other answer, you make want to use extrude to create something that dimensionally is similar to a square but has bevels. One example would be if you were trying to draw dice and wanted to round the edges.

If all you want is a cube why are you extruding? Why don't you use the CubeGeometry.

Related

How to create a Points (Mesh) of TextGeometry?

I am creating a TextGeometry but not able to convert in Points like a sphere or like a detailed 3d object.
In the below image I have created a sphere using
var dotGeometry = new THREE.SphereBufferGeometry(2, 100, 100);
var dotMaterial = new THREE.PointsMaterial({ size: 1, sizeAttenuation: false });
var dot = new THREE.Points(dotGeometry, dotMaterial);//new THREE.MeshBasicMaterial()
scene.add(dot);
and the for text I use
const fontloader = new THREE.FontLoader();
fontloader.load('./models/font.json', function (font) {
const textgeometry = new THREE.TextGeometry('Hello', {
font: font,
size: 1,
height: 0.5,
curveSegments: 12,
bevelEnabled: false,
bevelThickness: 10,
bevelSize: 8,
bevelOffset: 0,
bevelSegments: 5
});
var dotMaterial = new THREE.PointsMaterial({ size: 1, sizeAttenuation: false });
let textmesh = new THREE.Points(textgeometry, dotMaterial) //new THREE.MeshBasicMaterial({
// color: 0xffffff,
// wireframe: true
// }));
textmesh.geometry.center();
scene.add(textmesh);
// textmesh.position.set(0, 2, 0)
});
So how to create a geometry having many points for text also, Why I am not able to use MeshBasicMaterial for Points in sphere?
What you see is actually the expected result. TextGeometry produces a geometry intended for meshes. If you use the same data for a point cloud, the result is probably not as expected since you just render each vertex as a point.
When doing this with TextGeometry, you will only see points at the front and back side of the text since points in between are not necessary for a mesh.
Consider to author the geometry in a tool like Blender instead and import it via GLTFLoader.

Three.js how to add circle in center of scene

I work with sphere image and use for it Three.js and I need to add some small object like aim in center of the sphere, and when I will move scene this object should be always in center of scene.
var cubeGeometry = new THREE.CircleGeometry(2, 100);
var cubeMaterial = new THREE.MeshBasicMaterial({color: 0xffffff, side: THREE.DoubleSide, transparent: true, opacity: 0.5, depthTest: false});
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);
this.camera.add(cube)
cube.position.set( 0, 0, -55 );
you can add the aim to the sphere and it will move with it in the middle:
sphere.add(aim);

three js envMap using one texture

I have a code:
var urls = [ 'img/effects/cloud.png','img/effects/cloud.png','img/effects/cloud.png','img/effects/cloud.png','img/effects/cloud.png','img/effects/cloud.png' ];
var textureCube = THREE.ImageUtils.loadTextureCube( urls, new THREE.CubeRefractionMapping );
var cubeMaterial3 = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: textureCube, refractionRatio: 0.98, reflectivity:0.9 } );
mesh = new THREE.Mesh( wormholeGeom, cubeMaterial3 );
scene.add(mesh);
This successfully works and inserts sphere with refraction map.
But i do not using skybox, but skysphere where is whole sky represented by one texture.
Is the way to make a refraction mapping from one texture?
Not by array of six textures?
I tried many thinks (THREE.ImageUtils.loadTexture,THREE.SphericalRefractionMapping too) but no luck.
Documentation is "TODO".
This is my goal, but with one texture in skydome. There are used 6 textures in square to make sky.

Using multiple materials with THREE.CylinderGeometry - create a wheel from cylinder

I want to create a wheel from cylinder (because importing 3D models makes it slower). But I cannot use multiple materials with cylinder geometry. It uses only the first material in an array.
var geometry = new THREE.CylinderGeometry(this.diameterWheel/2,this.diameterWheel/2,this.lastikGenisligi, 20, 4);
var materialArray = [];
materialArray.push(new THREE.MeshBasicMaterial( { color: 0x000000 }));
materialArray.push(new THREE.MeshBasicMaterial( { map: THREE.ImageUtils.loadTexture( '../textures/wheel.png' ) }));
materialArray.push(new THREE.MeshBasicMaterial( { color: 0x0000FF }));
materialArray.push(new THREE.MeshBasicMaterial( { color: 0xFF0000 }));
var material = new THREE.MeshFaceMaterial(materialArray);
var mesh = new THREE.Mesh(geometry, material);
What I want to create is a wheel which will have wheel.png wheel image on upper and bottom sides and black coverage on between them.
You need to loop through each face on the cylinder and tell which of the array materials the face uses.
geometry.faces[a].materialIndex = b;
Where a is the face index. You need to figure out yourself which face is which to choose the correct material through some system, ie. faces 0-10 with one color, etc. This depends on the cylindergeometry parameters. And b is the material index.

How can I control line width using the THREE.js createMultiMaterialObject function?

I'm experimenting with the createMultiMaterialObject function in THREE.js to create shaded objects that also display a wireframe. The problem is the lines appear broken & don't seem to respond to the wireframeLinewidth parameter.
My materials are defined as follows:
var mat1 = new THREE.MeshBasicMaterial( { color: 0xd02000, transparent: true, blending: THREE.AdditiveBlending } )
var blackLines = new THREE.MeshBasicMaterial( { color: 0x000000, wireframe: true, wireframeLinewidth: 4 } );
And the object is here:
var object = THREE.SceneUtils.createMultiMaterialObject( new THREE.CubeGeometry( 100, 100, 100, 4, 4, 4 ), materials );
object.position.set( -100, 150, 0 );
scene.add( object );
But this produces this result:
Any help would be appreciated. Thanks!
Your code is fine. Are you running Windows? If so, it is possibly an ANGLE issue, in which case the line width cannot be changed. See this related question.
If you are unable to increase the line width, a work-around in your case is to make the wireframe mesh just a bit larger than the solid mesh, like so:
object.children[ 1 ].scale.multiplyScalar( 1.01 );
If you do that, there will be no more broken lines and it will be beautiful. :-)
three.js r.55

Resources