Layer multiple materials onto SphereGeometry in three.js - three.js

I'm attempting to create a sphere in three.js with a base material and a transparent png material over the top. I found this answer helpful in understanding how to load multiple materials. However when I try to apply this to SphereGeometry rather than BoxGeometry as in the example, only the second material is visible, with no transparency.
http://jsfiddle.net/oyamg8n3/1/
// geometry
var geometry = new THREE.BoxBufferGeometry( 10, 10, 10 );
geometry.clearGroups();
geometry.addGroup( 0, Infinity, 0 );
geometry.addGroup( 0, Infinity, 1 );
geometry.addGroup( 0, Infinity, 2 );
geometry.addGroup( 0, Infinity, 3 );
// textures
var loader = new THREE.TextureLoader();
var splodge = loader.load( 'https://threejs.org/examples/textures/decal/decal-diffuse.png', render );
var cat = loader.load('https://images.unsplash.com/photo-1518791841217-8f162f1e1131?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1950&q=80.jpeg', render)
// materials
var catMat = new THREE.MeshPhongMaterial( {
map: cat,
} );
var splodgeMat = new THREE.MeshPhongMaterial( {
map: splodge,
alphaTest: 0.5,
} );
var materials = [ catMat, splodgeMat ];
// mesh
mesh = new THREE.Mesh( geometry, materials );
scene.add( mesh );
Can I use these same principles for
var geometry = new THREE.SphereGeometry( 5, 20, 20 );

It does work if you use SphereBufferGeometry and not SphereGeometry. Notice that both classes have a different super class. You want to work with the BufferGeometry version.
Demo: http://jsfiddle.net/r6j8otz9/
three R105

Related

How can I apply Texture on Cube using Three.js

// Make a cube with Lambert material
// ---------------------------------
// Lower fragments can increase performance
var cubeWidth = cubeSize,
cubeHeight = cubeSize,
cubeDepth = 10,
cubeQuality = 1;
// create the cube's material
var cubeMaterial = new THREE.MeshLambertMaterial(
{
color: 0xb22222
}
);
// create a cube with sphere geometry and the meterial
cube = new THREE.Mesh(
new THREE.BoxGeometry(
cubeWidth,
cubeHeight,
cubeDepth,
cubeQuality,
cubeQuality,
cubeQuality
),
cubeMaterial);
lift the cube to half of the playing space height
cube.position.z = fieldDepth/2;
set the cube x position in the left of the play field
cube.position.x = -fieldWidth/3;
----------add the cube to the scene-------------------------
scene.add(cube);
I have tried ;
var texture = new THREE.TextureLoader();
var texture1 = texture.load('scripts/kan.png');
cube = new THREE.Mesh(
new THREE.BoxGeometry(
cubeWidth,
cubeHeight,
cubeDepth,
cubeQuality,
cubeQuality,
cubeQuality
));
var cubeMaterial = new THREE.MeshBasicMaterial(
{
map: texture1
//color: 0xb22222
}
);
// create a cube with sphere geometry and the meterial
mesh = new THREE.Mesh( cube, cubeMaterial );
And this, but it didn't work
const texture = new THREE.TextureLoader().load( 'kan.png' );
var cubeMaterial = new THREE.MeshLambertMaterial(
{
//color: 0xb22222
map: texture
}
);
I am also getting the following error : THREE.Material: 'map' parameter is undefined

texture wrapping is not repeating as it should be

I'm trying to wrap a texture for the floor, but it doesn't work - the texture is not repeated 5 times as it should be. Here s the code I used:
var floorTexture = new THREE.ImageUtils.loadTexture( 'textures/floor.jpg' );
floorTexture.wrapS = floorTexture.wrapT = THREE.RepeatWrapping;
floorTexture.repeat.set( 5, 1 );
var floorMaterial = new THREE.MeshPhongMaterial( { map: floorTexture, side: THREE.DoubleSide } );
var floorGeometry = new THREE.PlaneGeometry( 45, 44.5 );
var floor = new THREE.Mesh( floorGeometry, floorMaterial );
You can see the project here : http://provasitimek.herobo.com/Tesi9.2/ - choose the userGroup, then the paths, the startPoint end the endPoint to visit the model
You have to make sure that your texture has sizes which are power of two.
Generally WebGL does not support NPOT (non-power of two) textures. There are some exceptions though outlined at Non power of two textures

Repeating texture of the PlaneGeometry

The way of reproduction of the texture, independent of the extent of object is necessary to me. If, for example, to do:
var geometry = new THREE.PlaneGeometry( 400, 400, 10, 10 );
var Texture = THREE.ImageUtils.loadTexture( 'textures/texture.png' );
Texture.wrapS = Texture.wrapT = THREE.RepeatWrapping;
Texture.repeat.set( 2, 1 );
var material = new THREE.MeshBasicMaterial({
map: Texture,
side: THREE.DoubleSide,
});
var mesh = new THREE.Mesh( geometry, material );
mesh.position.set(-400,0,0);
scene.add( mesh );
var mesh = new THREE.Mesh( geometry.clone(), material.clone() );
mesh.scale.x = 2;
mesh.position.set(400,0,0);
scene.add( mesh );
result here
How to redefine texture to receive the following result?
here

Canvas renderer crashes when using multiple geometry in three.js

Based on certain parameters am creating multiple sphere geometries by specifying different PI and theta values. For example
var parent = new THREE.Object3D();
scene.add( parent );
var geometry = new THREE.SphereGeometry( 5, 24, 16, 0 * Math.PI/2, Math.PI/2 );
var material = new THREE.MeshLambertMaterial( { map: texture0 } );
mesh = new THREE.Mesh( geometry, material );
parent.add( mesh );
var geometry = new THREE.SphereGeometry( 5, 24, 16, 1 * Math.PI/2, Math.PI/2 );
var material = new THREE.MeshLambertMaterial( { map: texture1 } );
mesh = new THREE.Mesh( geometry, material );
parent.add( mesh );
var geometry = new THREE.SphereGeometry( 5, 24, 16, 2 * Math.PI/2, Math.PI/2 );
var material = new THREE.MeshLambertMaterial( { map: texture2 } );
mesh = new THREE.Mesh( geometry, material );
parent.add( mesh );
var geometry = new THREE.SphereGeometry( 5, 24, 16, 3 * Math.PI/2, Math.PI/2 );
var material = new THREE.MeshLambertMaterial( { map: texture3 } );
mesh = new THREE.Mesh( geometry, material );
parent.add( mesh );
When i create more than one geometry, it works fine with THREE.WebGLRenderer but when i use THREE.CanvasRenderer() the browser crashes. How to fix the issue. I want my application to run on IE10 and below which only supports THREE.CanvasRenderer.
Thanks in advance.

Different material on back and frontside of extruded shape

I'm trying to apply different material on front and back sides of extruded shape, but cannot figure out where to put side: THREE.FrontSide and side: THREE.BackSide. Where they should be putted?
My relevant code part is:
var materialFront = new THREE.MeshPhongMaterial({ ambient: 0xffffff, map: frontTexture });
var materialSide = new THREE.MeshPhongMaterial({color: 0xE68A00, ambient: 0xffffff});
var extrusionSettings = {
amount: 10,
bevelEnabled: false,
bevelThickness: 0.2,
bevelSize: 0.2,
bevelSegments: 8,
material: 0,
extrudeMaterial: 1
};
var geometry = new THREE.ExtrudeGeometry(shapes, extrusionSettings);
var materials = [materialFront, materialSide];
var material = new THREE.MeshFaceMaterial(materials);
mesh = new THREE.Mesh(geometry, material);
UPDATE:
According to WestLangley's comment I succeeded in adding the different texture to backfaces:
// ...
var materials = [materialFront, materialSide, materialBack];
// ...
for ( var face in mesh.geometry.faces ) {
if (mesh.geometry.faces[ face ].normal.z == 1) mesh.geometry.faces[ face ].materialIndex = 2;
}
After you create your mesh geometry, and before the first call to render(), you have to change the materialIndex to 2 for the back faces. Then, add a third material in your material array.
You can identify the back faces by their face normals. Face normals for faces on the back of the geometry should all point in the same direction.
three.js r.58
Try using:
var materialFront = new THREE.MeshPhongMaterial({ ambient: 0xffffff, map: frontTexture, side: THREE.FrontSide });
var materialSide = new THREE.MeshPhongMaterial({ color: 0xE68A00, ambient: 0xffffff, side: THREE.BackSide });
even though you should probably lower your ambient contribution and give a color to the FrontSide material.
Then:
var materials = [materialFront, materialSide];
scene.add( THREE.SceneUtils.createMultiMaterialObject( geometry, materials ));

Resources