ImageUtils.loadTexture with callback in Canvas Renderer - javascript

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() { ... } )
});

Related

three.js Apply image on existing object

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
} );

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} );
} );

Three.js LightMap not showing?

I can't make lightMap showing on my mesh, here's the code:
loader.load('model.ctm', function (geometry) {
var lm = THREE.ImageUtils.loadTexture('lm.jpg');
var m = THREE.ImageUtils.loadTexture('t.jpg');
var material = new THREE.MeshBasicMaterial({
lightMap: lm,
map: m,
});
geometry.faceVertexUvs[1] = geometry.faceVertexUvs[0];
mesh = new THREE.Mesh(
geometry,
material
);
scene.add(mesh);
}, {useWorker: true});
While i'm not using geometry.faceVertexUvs[1] = geometry.faceVertexUvs[0]; , the mesh is disappear with no console error.
When i use it, mesh still disappear and console happen this error:
TypeError: geometry.faceVertexUvs is undefined
How to fix this?
Thanks.
The problems fixed when change to normal Geometry, BufferGeometry not supported yet.

Categories

Resources