Is it a Three.js bug with collada loader? - javascript

There is a three.js demo here: http://mrdoob.github.com/three.js/examples/webgl_loader_collada.html
It works perfectly, but if I want to use canvas renderer instead of webgl, it's buggy.
renderer = new THREE.CanvasRenderer();
I can't see the texture (the object is white), and the animation also doesn't works. Is it a bug in three.js, or I have to modify more in the code?
Thanks in advance

CanvasRenderer has several limitations. See Issue 1026.
Default skin material is an instance of THREE.MeshLambertMaterial, but you can do a quick overwrite with a THREE.MeshBasicMaterial instance with the original texture map:
...
skin = collada.skins[ 0 ];
skin.material = new THREE.MeshBasicMaterial({map: skin.material.map});
...
And AFAIK CanvasRenderer doesn't support morph targets (animation).

Related

Lighting glb models in Three JS with minimal shadows

Not sure if I worded my title right but I'm getting my feet wet with three JS. Right now I have a simple glb model that I would like to import into my scene, but I can't get the lighting right. The image below is what I want to accomplish.
But when I import my glb into my scene and add some lighting this is what it looks like
The model is quite dark and I can't get it to light up ideally. I've tried adding ambient lights top-down, point lights as a child to the camera instance, hemisphere lights, etc. but I just can't get it to look right. Below is the code for the current lighting; I'm trying to achieve the look by using point lights atm.
var light = new THREE.PointLight( 0xffffff, 10 );
light.position.z = 10
camera.add(light)
var light2 = new THREE.PointLight( 0xffffff, 10 );
light2.position.set(0, -20, 30)
scene.add(light2)
If anyone could give me some insights as to what is the proper way to achieve what I am desiring that will be great.
So I did some digging in, and it turns out that Blender includes this thing called an environment map
https://discourse.threejs.org/t/exporting-blender-scene-lighting-issues/11887/8
So I had to recreate the environment in my scene as well.
After importing RoomEnvironment like so:
import { RoomEnvironment } from 'three/examples/jsm/environments/RoomEnvironment';
I created the room environment:
const environment = new RoomEnvironment();
const pmremGenerator = new THREE.PMREMGenerator( renderer );
scene.environment = pmremGenerator.fromScene( environment ).texture;
Then I added the following attributes to my scene object:
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.2;
renderer.outputEncoding = THREE.sRGBEncoding;
After that, it lights up just as fine! I honestly don't really know what these toneMapping stuff do at the moment, but for now this solves my problem.

Three.js texture on material

I'd like to apply a custom image texture (.bmp or .jpg) on a material loaded from Blender and used in my project via the JSONLoader method.
There is no bug but the render of the material with the texture is bad looking.
You can see it here: http://image.noelshack.com/fichiers/2014/18/1399215240-stack.png
I'd like to get rid of these "rays" on my material. Here is the code I use to load my material/texture:
var texture = THREE.ImageUtils.loadTexture('/Game/models/textures/black.jpg');
var currentMaterial = new THREE.MeshBasicMaterial({ map: texture });
var currentModel = new THREE.Mesh(geometry, currentMaterial);
The "geometry" variable is the result of the callback of the JSONLoader.Load method.
I'd like to know if the problem comes from the image texture or from the code. And what is the best way to load a material created in Blender and exported as a JS file and loaded with the JSONLoader. I'm not sure if I use the best method when I use the "THREE.MeshBasicMaterial" constructor.
Thanks

Collada model faces not displaying correctly in three.js

After importing a collada model into three.js, some of the model's faces are only visible from the inside of the model and not from the outside.
How can I fix the problem with the faces in question?
Is it possible to have the model's faces visible from both sides?
The reason it doesn't work properly is because your file has this double_sided flag set:
<effect id="material_3_4_0-effect" name="material_3_4_0-effect">
<profile_COMMON>
...
<extra>
<technique profile="GOOGLEEARTH">
<double_sided>1</double_sided>
</technique>
</extra>
</profile_COMMON>
</effect>
The three.js ColladaLoader doesn't look for this flag and set doubleSided on the material like it should. I've filed a bug for the issue.
To fix the faces being oriented incorrectly, load the model into a 3D modeling program like Blender and flip the normals of the faces that aren't displaying correctly.
Three.js meshes have a doublesided property you can set which will usually allow you to display the model with the faces visible from both sides.
Here's a short example of how to load a collada mesh and enable double-sided rendering.
var loader = new THREE.ColladaLoader();
loader.load('path/to/mesh.dae', loadModel);
function loadModel(geom) {
var mesh = new THREE.Mesh(geom, new THREE.MeshBasicMaterial());
mesh.doublesided = true;
scene.add(mesh);
}
And a live example: http://jsfiddle.net/r7Yq2/

How to update material of cube on runtime using WebGL?

I'm using three.js for doing animations. I want to dynamically update a material of a cube mesh. Here is example:
// create cube geometry
var material1 = [new THREE.MeshBasicMaterial({color:0xBEE2FF}),.....];
var geometry = new THREE.CubeGeometry(50, 50, 50,0,0,0,material1 );
var cube = new THREE.Mesh(geometry, new THREE.MeshFaceMaterial());
// ...
var material2 = [new THREE.MeshBasicMaterial({color:0xFFFFFF}), ...];
cube.geometry.materials = material2;
If I use CanvasRenderer, it works. But when I change to WebGL Renderer, it throws error: Uncaught TypeError: Cannot read property 'map' of undefined
How to update the material of a cube on runtime using WebGL?
With a code fragment, it is difficult to know what is causing the error, but you cannot change materials that involve the presence or not of a texture. Try keeping all of your materials of the same type. Also, you may need to set material.needsUpdate flag to true.
You can find more detail and examples in the Three.js wiki about how to update things with WebGLRenderer.
https://github.com/mrdoob/three.js/wiki/Updates
Also, here is a fiddle that does something similar to what you appear to be trying to do: http://jsfiddle.net/2FZU7/51/
EDIT: fiddle updated for three.js r.58
I think the issue is that you're setting 'materials' and not 'material' on your cube.
cube.material = material2;
material.map = texture;
material.needsUpdate = true;

How do I use texture on a sphere in three.js

I've downloaded a sphere example from: http://aerotwist.com/lab/getting-started-with-three-js/ and I can see the nice red sphere. I'd like to use a texture on it. I've tried this:
var texture = THREE.ImageUtils.loadTexture("ball-texture.jpg");
texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;
texture.repeat.set( 125, 125 );
texture.offset.set( 15, 15 );
texture.needsUpdate = true;
var sphereMaterial = new THREE.MeshBasicMaterial( { map: texture } );
var sphere = new THREE.Mesh(new THREE.Sphere(radius, segments, rings),sphereMaterial);
but I can't see anything, all is black. Does anyone have a working example for sphere texture?
You might have two problems.
First, try loading it like this:
var texture = THREE.ImageUtils.loadTexture('ball-texture.jpg', {}, function() {
renderer.render(scene, camera);
});
texture.needsUpdate = true;
Make sure that the texture size is a power of two (512x512px for IE).
Are you using Firefox? This could be a problem in your browser. Firefox uses some kind of cross-site-blocker for textures. The result is black instead. Take a look at this site for more info: http://hacks.mozilla.org/2011/06/cross-domain-webgl-textures-disabled-in-firefox-5/
Do you have a rendering loop, or did you render the scene just once?
You need to have a rendering loop so that when the THREE.ImageUtils loads the image and updates the texture, you re-render the scene with the now updated texture.
All the three.js examples seem to rely on this technique. I.e., Fire off several async operations involving a fetch of a remote resource, start rendering loop, let scene be updated as remote resources arrive.
IMHO this is Three.js's biggest gotcha for Javascript newbs (like me) who are not familiar with how async operations work.
I had this problem, but if you are loading the html as a file (i.e. locally not a webserver), many browsers (chrome for e.g.) will not allow you to load images in the standard three.js way as it is a security violation.

Categories

Resources