Tuesday, July 31, 2012

Image Materials in Three.js

‹prev | My Chain | next›

It's alpha release date for Gaming JavaScript, so this will (hopefully) be a short post.

In Gladius / CubicVR.js, I got pretty good at applying images to the objects in my animations. I would like understand how to do the same in Three.js. I don't think I need to get into bump maps and the like. But it would be nice to at least put a face on my avatar.

So I create a 256 pixel high "face" image (remember that 256 is a magic number):


Next, I load that image and attempt to create a texture from it:
function buildAvatar() {
  // ...
  var img = new Image();
  img.src = 'face.png';
  var texture = new THREE.Texture(img);

  var head_material = new THREE.MeshPhongMaterial({map: texture});
  var head_geometry = new THREE.SphereGeometry(75);
  var head = new THREE.Mesh(head_geometry, head_material);
  head.position.y = (100 + 35) * .8;
  avatar.add(head);
  // ...
}
With that, I get:


Well, that's not quite what I was hoping for.

Ah! There are no lights in this drawing. I am using nothing but normal materials (they "shine" on their own). So let's add a light to the avatar:
  var light = new THREE.PointLight(0xffffff, 10);
  light.position.set(50, 150, 150);
  avatar.add(light);
Hrm... that does not actually help. Now I just have a shiny black head:


At this point, I am at a bit of a loss, so I start digging through Three.js code. Eventually, I happen across the ImageUtils, which include a loadTexture() function that seems to be doing just about the same thing that I'm trying here. In fact, the code is very close to what I had tried, save for an onload() callback on the image that marks the texture as needing an update.

It seems that Three.js will silently ignore the image without this. So I copy the onload() function into my code:
  var img = new Image();
  var texture = new THREE.Texture(img);
  img.onload = function () { texture.needsUpdate = true; };
  img.src = 'face.png';
  texture.needsUpdate = true;
And behold, I have my avatar with a face:


Sure, that face leaves much to be desired, but it is a functioning start. And a good place to stop tonight. Alpha copies of Gaming JavaScript coming soon!


Day #464

No comments:

Post a Comment