three.js Apply image on existing object - javascript

I try to add an img on one object to change his aspect. But all my test result by white object...
The purpose is juste to apply an image on object (all face). He my test code :
var obj = scene.getObjectByName('wall_20_118')
var texture = new THREE.ImageLoader().load( 'core/img/3d/shutter.jpg' );
material = new THREE.MeshBasicMaterial({map: texture,side:THREE.DoubleSide });
obj.material = material
obj.material.map.needsUpdate = true
The object turn to white but I can see my image.
How can I do that ?
Thank in advance

You should be using the THREE.TextureLoader and it's asynchronous, which means that the image is loaded and a callback function will be invoked once the loading finished and the image can be used as a texture on the object.
You would have to change your code like this:
var obj = scene.getObjectByName('wall_20_118');
new THREE.TextureLoader().load( 'core/img/3d/shutter.jpg', function onLoad(texture) {
var material = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.DoubleSide
});
obj.material = material
} );

Related

Display svg in three.js using WebGLRenderer

Can i show a svg in a three.js scene using the WebGL renderer? I know that this can be done using the SVG renderer and loader but I can't use it for my problem.
Thanks.
You can use the Sprite object and specify your svg file in the TextureLoader(), like so:
var map = new THREE.TextureLoader().load( "sprite.svg" );
var material = new THREE.SpriteMaterial( { map: map, color: 0xffffff, fog: true } );
var sprite = new THREE.Sprite( material );
scene.add( sprite );
You can read more here: Three.js - Sprite

Add background to THREE scene

I am trying to add a background to a THREE scene, but I cannot get it to work. I followed the advice given here and here without success.
Here are the lines I added to my (complex) code:
// Load the background texture
var loader = new THREE.TextureLoader();
var texture = loader.load( 'textures/stars_texture2956.jpg' );
var backgroundMesh = new THREE.Mesh(
new THREE.PlaneGeometry(2, 2, 0),
new THREE.MeshBasicMaterial({
map: texture
}));
backgroundMesh.material.depthTest = false;
backgroundMesh.material.depthWrite = false;
// Create your background scene
backgroundScene = new THREE.Scene();
backgroundCamera = new THREE.Camera();
backgroundScene.add(backgroundCamera );
backgroundScene.add(backgroundMesh );
and the render function looks like this:
function render() {
renderer.render(backgroundScene, backgroundCamera);
renderer.render( scene, camera );
}
Still I do not see the background (it is still white), but everything else works as expected. Is there a way to fix this?
If you wish to add a static background to your scene then the easiest way is to make the background of your scene transparent and place an image under canvas:
var renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setClearColor( 0xffffff, 0);
If you wish to create panoramic background which changes when you rotate camera then you need to create a skybox - a big mesh around your scene textured with a set of textures which cover 360 degrees of view. Have a look at this example:
http://threejs.org/examples/#webgl_materials_envmaps
The map is undefined because the TextureLoader Constructor expects a manager, not an url.
// instantiate a loader
var loader = new THREE.TextureLoader();
// load a resource
var texture = loader.load( 'textures/land_ocean_ice_cloud_2048.jpg' );
http://threejs.org/docs/#Reference/Loaders/TextureLoader
To solve your problem with the two scenes, you need to disable autoClear. The second renderer call clears the first one. Set after initializing: renderer.autoClear = false;. Now manually clear in your render-function:
function render() {
renderer.clear(); // <-
renderer.render(backgroundScene, backgroundCamera);
renderer.render( scene, camera );
}
try to coding like this
THREE.ImageUtils.crossOrigin = '';
var img = 'http://bpic.588ku.com/back_pic/03/92/40/4957e29f80d8a4a.jpg!ww650';
var grass = THREE.ImageUtils.loadTexture(img);
new THREE.MeshLambertMaterial({ map: grass });
it works for me
I have found a solution: Instead of creating a different scene and not knowing how to add cameras/whatever so it get rendered correctly, just add the background mesh to the actual scene.
The code then is as follows:
// Load the background texture
var loader = new THREE.TextureLoader();
var texture = loader.load( 'textures/messier-41.jpg' );
var backgroundMesh = new THREE.Mesh(
new THREE.PlaneGeometry(2048, 2048,8,8),
new THREE.MeshBasicMaterial({
map: texture
}));
backgroundMesh.material.depthTest = false;
backgroundMesh.material.depthWrite = false;
which must be put before the code that adds the other parts of the scene.

"THREE.NearestFilter" or "THREE.LinearFilter" Causes the Black Plane

While I was working with THREE.js library, I got that kind of notification:
THREE.WebGLRenderer: Texture is not power of two. Texture.minFilter
should be set to THREE.NearestFilter or THREE.LinearFilter.
So, I tried to fix it. It works, when I put the filter:
var groundGeometry = new THREE.PlaneBufferGeometry( 5000, 5000, 96, 96 );
var grassTexture = THREE.ImageUtils.loadTexture("images/grass.jpg");
grassTexture.minFilter = THREE.LinearFilter;//here is the filter
var groundMaterial = new THREE.MeshBasicMaterial( {map: grassTexture, side: THREE.DoubleSide} );
var groundPlane = new THREE.Mesh(groundGeometry, groundMaterial);
scene.add( groundPlane );
However, I tried another way, but at the end I got just the black plane:
var groundGeometry = new THREE.PlaneBufferGeometry( 5000, 5000, 96, 96 );
var groundMaterial = new THREE.MeshBasicMaterial( {map: THREE.ImageUtils.loadTexture({image: "images/grass.jpg", minFilter: THREE.LinearFilter}), side: THREE.DoubleSide} );
var groundPlane = new THREE.Mesh(groundGeometry, groundMaterial);
scene.add( groundPlane );
You are getting a black plane in the second case because you are not passing the proper arguments to THREE.ImageUtils.loadTexture(). You are passing an object {}. You would have to do something like this:
var groundMaterial = new THREE.MeshBasicMaterial( {
map: THREE.ImageUtils.loadTexture( "images/grass.jpg" ),
side: THREE.DoubleSide
} );
groundMaterial.map.minFilter = THREE.LinearFilter;
It is true that the texture loading is asynchronous, but without knowing the rest of your code, it cannot be determined if that is an issue here.
BTW, you likely do not need 18,000 faces in your PlaneBufferGeometry. Try
groundGeometry = new THREE.PlaneBufferGeometry( 5000, 5000, 1, 1 );
three.js r.71
The texture is not downloaded and ready for use when you think it is.
In the first case the second statement requests an asynchronous loading of the texture. Two statements later the texture is assigned to a variable. It works just by luck.
In the second case you download and assign a texture all in one statement. Hardly enough time for the texture to be downloaded.
The proper way: (taken from http://threejs.org/docs/#Reference/Loaders/ImageLoader)
var groundMaterial;
...
// instantiate a loader
var loader = new THREE.ImageLoader();
// load a image resource
loader.load(
// resource URL
'images/grass.jpg',
// Function when resource is loaded
function ( image ) {
// here you are guaranteed that the texture has downloaded so you can do something with it.
groundMaterial = new THREE.MeshBasicMaterial( {map: image, side: THREE.DoubleSide} );
} );

JSONLoader and textures R61

I recently updated to version r61 from r58 and have found that with JSONLoader even if i only want to return geometry I am still getting a 404 on a texture call from a shader in my model.js file.
loadModel: function( label, domobject, callback ) {
var model_path = '/models/js/' + label + '.js';
var texture_place = '/textures/' + label + '.jpg';
var loader = new THREE.JSONLoader()
function onLoad(event) {
domobject.append( Set.renderer.domElement );
}
var texture = new THREE.ImageUtils.loadTexture( texture_place, null, onLoad );
loader.load( model_path, function ( geometry ) {
var material = new THREE.MeshLambertMaterial({map: texture});
Set.asset = new THREE.Mesh( geometry, material );
Set.asset.position.x = Set.asset.position.y = Set.asset.position.z = 0;
Set.asset.scale.x = Set.asset.scale.y = Set.asset.scale.z = 1;
if ( callback ) callback();
});
},
I am setup this way as to prevent models from loading up black and then having the texture pop on, which is working great. The behavior I expected with JSONLoader was that
loader.load(model_path, function (geometry, materials) would dig into the model file and look for materials and textures and that just specifying 'geometry' would ignore shader / texture.
Furthermore,
Is there a more simple way to use JSONLoader it's texturePath argument and an onLoad function to ensure that my geo doesn't get rendered before a texture is finished loading ?
Thanks!

ImageUtils.loadTexture with callback in Canvas Renderer

i'm using three.js revision 53
when loading a texture in Canvas Renderer (IE on Win7) and adding a callback for the onLoad event, the texture is not getting displayed. When i remove the callback function, the texture is getting displayed as expected:
// NOT WORKING with callback added
var material = new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture('text_build.png', {}, function()
{
//do something
})
});
var plane = new THREE.Mesh(new THREE.PlaneGeometry(135, 135), material);
plane .overdraw = true;
scene.add(plane );
// WORKING without callback
var material = new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture('text_build.png')
});
var plane = new THREE.Mesh(new THREE.PlaneGeometry(135, 135), material);
plane .overdraw = true;
scene.add(plane );
When running the same code in WebGL Renderer (FF,Chrome on WIn7), both examples work just fine.
Maybe someone can point me to the mistake i'm obviously doing here.
Thanks a lot.
Try this:
var material = new THREE.MeshBasicMaterial({
map: THREE.ImageUtils.loadTexture( 'text_build.png', new THREE.UVMapping(), function() { ... } )
});

Categories

Resources