I wonder if a textured geometry can take lighting in three.js. In my scene, all materials get great lighting with spotLight and directionalLight except for materials with texture assignment like this:
var geometry = new THREE.OctahedronGeometry(1, 0)
var orange = new THREE.TextureLoader().load( 'img/orange.jpg' );
orange.wrapS = THREE.RepeatWrapping;
orange.wrapT = THREE.RepeatWrapping;
orange.repeat.set( 4, 2);
var material = new THREE.MeshBasicMaterial({
map:orange, side:THREE.DoubleSide
});
var oct0 = new THREE.Mesh( geometry, material );
oct0.castShadow = true; //default is false
oct0.receiveShadow = false; //default
scene.add( oct0 );
oct0.position.x = 0;
oct0.position.y = 5;
oct0.position.z = 0;
I am using Chrome. Safari and three.js r89. Thanks for any advice!
MeshBasicMaterial does not respond to lights.
There are other built-in materials that do. For example, MeshLambertMaterial, MeshPhongMaterial, MeshStandardMaterial.
three.js r.89
Related
I created a simple mesh in Blender, which consist only from one textured plane.
Blender screenshot
I import it in three.js with this code:
var texture2 = new THREE.TextureLoader().load('models/TexturesCom_Branches0030_1_S.png');
loader.load("models/plant.json", function (geometry, materials) {
materials.forEach(function (material) {
material.alphaTest = 0.5;
});
mesh = new THREE.Mesh( geometry, materials );
mesh.customDepthMaterial = new THREE.MeshDepthMaterial( {
side: THREE.DoubleSide,
depthPacking: THREE.RGBADepthPacking,
map: texture2,
alphaTest: 0.5
} );
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
});
That's how mesh looks in three.js: #1
#2
As you can see, object casts shadow not only on the ground, but on itself.
I can turn receiveShadow off, but this is not a solution for me. This problem does not disappear, if I create THREE.PlaneGeometry manually.
I am learning OOP while using Three.js. I know, a hard way to do it. So i created a box in the scene. Now i want to change color of one face of that cube.
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 100, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.set(5, 5, 10);
var geo = new THREE.BoxGeometry(5,2,5);
var mat = new THREE.MeshBasicMaterial({color:0xff0ff0, side:THREE.DoubleSide});
var mesh = new THREE.Mesh( geo, mat);
scene.add(mesh);
//Right there i want to chance color of the face. Its not working
mesh.geometry.faces[5].color.setHex( 0xffffff );
var edge = new THREE.WireframeHelper( mesh, 0x00ff00 );
scene.add(edge);
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
renderer.render(scene, camera);
EDIT: the reason it did not work for me was the color i used 0xffffff. This program will work unless color is 0xffffff.
In your case, if you want to change the color of one face of the cube, you will need to specify vertexColors in your material.
var geo = new THREE.BoxGeometry( 5, 2, 5 );
var mat = new THREE.MeshBasicMaterial( { color:0xff0ff0, vertexColors: THREE.FaceColors } );
var mesh = new THREE.Mesh( geo, mat );
mesh.geometry.faces[ 5 ].color.setHex( 0x00ffff );
The rendered face color will be the specified face color tinted by the material color.
If you change a face color after the mesh has been rendered at least once, you will have to set:
mesh.geometry.colorsNeedUpdate = true;
three.js r.80
My mesh has a baked shadow texture.
Unfortunately I got a weird result If I move the camera to a steeper viewangle.
What can I do to prevent this ?
loader.load( "mesh.js", function(geometry){
var mesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( {
map: THREE.ImageUtils.loadTexture( "texture.png" ),
}));
scene.add(mesh);
});
Look at the example: http://threejs.org/examples/#webgl_materials_texture_anisotropy
Use:
var maxAnisotropy = renderer.getMaxAnisotropy();
texture.anisotropy = maxAnisotropy;
If you would like to learn more, you can look up Anisotropic Filtering.
I'm trying to load textures on a THREE.BufferGeometry, but the texture isn't showing up. If I use normal geometry, the texture shows up. Are textures unsupported with BufferGeometry or am I doing something wrong?
This works:
var geom = new THREE.BoxGeometry(1,1,1);
var texture = THREE.ImageUtils.loadTexture("texture.png");
var mat = new THREE.MeshPhongMaterial({ map:texture, side:THREE.DoubleSide });
scene.add( new THREE.Mesh(geom, mat) );
This doesn't:
var geom = new THREE.BoxGeometry(1,1,1);
var buffgeom = new THREE.BufferGeometry();
buffgeom.fromGeometry(geom);
var texture = THREE.ImageUtils.loadTexture("texture.png");
var mat = new THREE.MeshPhongMaterial({ map:texture, side:THREE.DoubleSide });
scene.add( new THREE.Mesh(buffgeom, mat) );
There is a bug in r68's BufferGeometry.fromGeometry().
Its been fixed in r69dev already.
I'm trying to create a long corridor with a repeating texture. How do I add a repeating texture and rotate a object (in this case a plane) at right angles to create the corridor wall's and ceiling?
var texture, material, plane;
texture = THREE.ImageUtils.loadTexture( "../img/texture.jpg" );
texture.wrapT = THREE.RepeatWrapping; // This doesn't seem to work;
material = new THREE.MeshLambertMaterial({ map : texture });
plane = new THREE.Mesh(new THREE.PlaneGeometry(400, 3500), material);
plane.doubleSided = true;
plane.position.x = 100;
plane.rotation.z = 2; // Not sure what this number represents.
scene.add(plane);
For an example of a repeating texture, check out the source of the example at:
http://stemkoski.github.com/Three.js/Texture-Repeat.html
I recommend the following changes to your code:
var texture, material, plane;
texture = THREE.ImageUtils.loadTexture( "../img/texture.jpg" );
// assuming you want the texture to repeat in both directions:
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
// how many times to repeat in each direction; the default is (1,1),
// which is probably why your example wasn't working
texture.repeat.set( 4, 4 );
material = new THREE.MeshLambertMaterial({ map : texture });
plane = new THREE.Mesh(new THREE.PlaneGeometry(400, 3500), material);
plane.material.side = THREE.DoubleSide;
plane.position.x = 100;
// rotation.z is rotation around the z-axis, measured in radians (rather than degrees)
// Math.PI = 180 degrees, Math.PI / 2 = 90 degrees, etc.
plane.rotation.z = Math.PI / 2;
scene.add(plane);
Was searching for solution without duplicating all my geometry.
Here you go ladies and gentlemen...
var materials = [new THREE.MeshBasicMaterial({map: texture, side: THREE.FrontSide}),
new THREE.MeshBasicMaterial({map: textureBack, side: THREE.BackSide})];
var geometry = new THREE.PlaneGeometry(width, height);
for (var i = 0, len = geometry.faces.length; i < len; i++) {
var face = geometry.faces[i].clone();
face.materialIndex = 1;
geometry.faces.push(face);
geometry.faceVertexUvs[0].push(geometry.faceVertexUvs[0][i].slice(0));
}
scene.add(new THREE.Mesh(geometry, new THREE.MeshFaceMaterial(materials)));
BOOM a Two Faced Plane for ya, the loop will also work with geometries with more faces, replicating each face and applying the BackSide texture to it.
Enjoy!
I was looking for the same thing and you've just used the property THREE.DoubleSide on the wrong object. You should use it on the material rather than on the mesh itself:
material.side = THREE.DoubleSide;
...nothing more !
Update 2019: Imageutil.loadTexture is deprecated,
Use THREE.TextureLoader() instead
new THREE.TextureLoader().load(
WOOD,
//use texture as material Double Side
texture => {
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.offset.x = 90/(2*Math.PI);
var woodMaterial = new THREE.MeshPhongMaterial({
map: texture,
side: THREE.DoubleSide
});
// Add Ground
groundMesh = new THREE.Mesh(
new THREE.PlaneGeometry(GRID_SIZE, GRID_SIZE, 32),
woodMaterial
);
//rotate
groundMesh.rotation.x = Math.PI / 2;
this.scene.add(groundMesh);
}
);