three.js: BufferGeometry and textures - javascript

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.

Related

three.js textured material does not take lighting

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

Is there a way to add different textures to an object with TextureLoader.load

I would like to add different textures to each face of a box but I am not sure if loader.load is the way to do it, right now I have:
loader.load('img/brick.jpg', function ( texture ){
var boxGeometry = new THREE.BoxGeometry( 3, 3, 3 );
var boxMaterial = new THREE.MeshLambertMaterial({
map: texture,
overdraw: 10
});
var box = new THREE.Mesh( boxGeometry, boxMaterial );
box.castShadow = true;
scene.add(box);
}
Is it possible to add more images in the loader.load or do I have to use a different method?
You can just load an image with loader.load, and store it in a variable:
var loader = new THREE.TextureLoader();
var brick = loader.load('img/brick.jpg');
var occlusion = loader.load('img/ao.jpg'); //Example texture
//More textures here
You can then apply it like so:
var boxGeometry = new THREE.BoxGeometry( 3, 3, 3 );
var boxMaterial = new THREE.MeshLambertMaterial({
map: brick,
aoMap: occlusion, //An example use
overdraw: 10
});
var box = new THREE.Mesh( boxGeometry, boxMaterial );
box.castShadow = true;
scene.add(box);
Instead of loading the texture and using an anonymous callback, just load the texture, store it in a variable, then apply where needed.

Is it possible to map multiple different textures to ONE face of a geometry in three.js?

Is it possible to map multiple different textures to one face of a geometry in three.js?
I don't want to create multiple faces and assign materialIndexes since the number of faces I need for the geometry changes during runtime.
Here is my last unsuccessful attempt (three.js r.71):
//get some materials
var materials = [];
materials.push(loadTextures(1));
materials.push(loadTextures(2));
materials.push(loadTextures(3));
materials.push(loadTextures(4));
var faceMaterial = new THREE.MeshFaceMaterial(materials);
//create objects
var wireframeObj = new THREE.Mesh(geometry.clone(), new THREE.MeshBasicMaterial({
wireframe: true,
color: 'red'
}));
var mainObj = new THREE.Mesh(geometry, faceMaterial);
scene.add(wireframeObj);
scene.add(mainObj);
camera.position.z = 100;
renderer.render(scene, camera);
function loadTextures(i) {
var texture = new THREE.Texture();
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(2, 2);
var image = new Image();
image.onload = function () {
texture.image = this;
texture.needsUpdate = true;
};
image.src = 'images/crate' + i + '.gif';
return new THREE.MeshBasicMaterial({ map: texture });
}
This produces the following:
while I want to see also crate2 to the right, crate3 above crate1 etc.

threecsg.js and subdivision modifier distorted geometry

I have the latest threecsg.js library and my use of it has been okay, except when I try to use the subdivision modifier after a CSG operation. Here is example code, modified from the example.html file that comes with the library from github:
var start_time = (new Date()).getTime();
var cube_geometry = new THREE.CubeGeometry( 3, 3, 3 );
var cube_mesh = new THREE.Mesh( cube_geometry );
cube_mesh.position.x = -6;
var cube_bsp = new ThreeBSP( cube_mesh );
var sphere_geometry = new THREE.SphereGeometry( 1.8, 12, 12 );
var sphere_mesh = new THREE.Mesh( sphere_geometry );
sphere_mesh.position.x = -7;
sphere_mesh.position.y -= 0;
var sphere_bsp = new ThreeBSP( sphere_mesh );
var subtract_bsp = cube_bsp.union( sphere_bsp );
var result = subtract_bsp.toMesh( new THREE.MeshLambertMaterial({ shading: THREE.SmoothShading, map: THREE.ImageUtils.loadTexture('texture.png') }) );
result.geometry.computeVertexNormals();
var smooth = result.geometry.clone() ;
smooth.mergeVertices();
var modifier = new THREE.SubdivisionModifier(0.1);
modifier.modify( smooth );
var mesh = new THREE.Mesh( smooth, new THREE.MeshPhongMaterial( { wireframe:true, color: 0xffffff } ) );
mesh.geometry.computeFaceNormals();
scene.add( mesh );
The above code unites a sphere and a cube. After this, it runs the resulting geometry through the subdivision modifier. The final output that is added to the scene has faces that are protruding from the object, other than that, the object does look smooth. Can anyone please help in solving this issue, that is, removing the protruding faces?

Load image as texture

I can load a image as texture when i create the 3d Object Three.js provides.
var handGeo = new THREE.CubeGeometry( 100, 100, 15 );
var texture = THREE.ImageUtils.loadTexture('../images/floor.jpg');
var handMat = new THREE.MeshBasicMaterial( {map: texture, color: 0x000000} );
var handMesh = new THREE.Mesh( handGeo, handMat );
But when i create the object(Cube) adding all the vertices and faces and merging the vertices in the end:
var vertices = [
new THREE.Vector3(p2.x,p2.y,p1.z), //C
new THREE.Vector3(p2.x,p2.y,p2.z), //G
new THREE.Vector3(p2.x,p1.y,p1.z), //D
new THREE.Vector3(p2.x,p1.y,p2.z), //H
new THREE.Vector3(p1.x,p2.y,p2.z), //F
new THREE.Vector3(p1.x,p2.y,p1.z), //B
new THREE.Vector3(p1.x,p1.y,p2.z), //E
new THREE.Vector3(p1.x,p1.y,p1.z) //A
];
var faces = [
new THREE.Face3(0,2,1),
new THREE.Face3(2,3,1),
new THREE.Face3(4,6,5),
new THREE.Face3(6,7,5),
new THREE.Face3(4,5,1),
new THREE.Face3(5,0,1),
new THREE.Face3(7,6,2),
new THREE.Face3(6,3,2),
new THREE.Face3(5,7,0),
new THREE.Face3(7,2,0),
new THREE.Face3(1,3,4),
new THREE.Face3(3,6,4)
];
var geometry = new THREE.Geometry();
geometry.vertices = vertices;
geometry.faces = faces;
geometry.computeCentroids();
geometry.mergeVertices();
var texture = THREE.ImageUtils.loadTexture('../images/floor.jpg');
var material = new THREE.MeshBasicMaterial( {map: texture, color: 0x000000} );
mesh = new THREE.Mesh(geometry, material);
I get this error:
[.WebGLRenderingContext]GL ERROR :GL_INVALID_OPERATION : glDrawElements: attempt to access out of range vertices in attribute 1

Categories

Resources