Three.js custom objLoader geometry lighting

空扰寡人 提交于 2020-01-23 07:46:51

问题


I have this object I'm loading with THREE.objLoader and then create a mesh with it like so:

mesh = new THREE.SceneUtils.createMultiMaterialObject(
  geometry,
  [
    new THREE.MeshBasicMaterial({color: 0xFEC1EA}),
    new THREE.MeshBasicMaterial({
      color: 0x999999,
      wireframe: true,
      transparent: true,
      opacity: 0.85
    })
  ]
);

In my scene I then add a DirectionalLight, it works and I can see my object, however it's like the DirectionalLight was an ambient one. No face is getting darker or lighter as it should be.

The object is filled with the color, but no lighting is applied to it. If someone can help me with that it would be much appreciated :)

What could I be missing ?

Jsfiddle here: http://jsfiddle.net/5hcDs/


回答1:


Demo: Simple cube, normals included in the OBJ file, no need to compute anything

Demo2: More complex shape, no normals included in the OBJ, need to compute them and flip them

On those demos I added arrows to help materialize the normals


Ok folks, thanks to Nilsaon Maël and mr doob I was able to understand the few things I was missing, being the total 3d noob that I am... I believe people starting to get into the 3d may find useful a little recap:

Basic 3d concepts

  • A 3d Face is made of some points (Vertex), and a vector called a normal, indicating the direction of the face (which side is the front and which one is the backside).

  • Not having normals can be really bad, because lighting is applied on the frontside only by default. Hence the black model when trying to apply a LambertMaterial or PhongMaterial.

  • An OBJ file is a way to describe 3D information. Want more info on this? Read this wikipedia article (en). Also, the french page provides a cube example which can be useful for testing.

Three.js tips and tricks

  • When normals are not present, the lighting can't be applied, hence the black model render. Three.js can actually compute vertex and face normals with geometry.computeVertexNormals() and/or geometry.computeFaceNormals() depending on what's missing

  • When you do so, there's a chance Three.js' normal calculation will be wrong and your normals will be flipped, to fix this you can simply loop through your geometry's faces array like so:

/* Compute normals */
geometry.computeFaceNormals();
geometry.computeVertexNormals();

/* Next 3 lines seems not to be mandatory */
mesh.geometry.dynamic = true
mesh.geometry.__dirtyVertices = true;
mesh.geometry.__dirtyNormals = true;

mesh.flipSided = true;
mesh.doubleSided = true;

/* Flip normals*/               
for(var i = 0; i<mesh.geometry.faces.length; i++) {
  mesh.geometry.faces[i].normal.x = -1*mesh.geometry.faces[i].normal.x;
  mesh.geometry.faces[i].normal.y = -1*mesh.geometry.faces[i].normal.y;
  mesh.geometry.faces[i].normal.z = -1*mesh.geometry.faces[i].normal.z;
}




回答2:


You have to use a MeshPhongMaterial. MeshBasicMaterial does not take light in account when computing fragment color.

However, when using a MeshPhongMaterial, your mesh becomes black. I've never used the OBJ loader, but are you sure your model normales are right ?

Btw : you probably want to use a PointLight instead. And its position should probably be set to the camera position (light.position = camera.position should do the trick, as it will allow the light to be moved when the camera position will be edited by the Controls).



来源:https://stackoverflow.com/questions/11032145/three-js-custom-objloader-geometry-lighting

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!