Three.js自定义objLoader几何照明

时间:2012-06-14 11:30:32

标签: three.js

我有这个对象我正在使用THREE.objLoader加载,然后像这样创建一个网格:

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

在我的场景中,我然后添加一个DirectionalLight,它可以工作,我可以看到我的对象,但它就像DirectionalLight是环境光。没有脸变得更暗或更浅。

对象用颜色填充,但不对其应用光照。 如果有人可以帮助我,我将不胜感激:)

我能错过什么?

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

2 个答案:

答案 0 :(得分:8)

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

演示2 More complex shape, no normals included in the OBJ, need to compute them and flip them

在这些演示中,我添加了箭头以帮助实现法线


好的伙计们,感谢NilsaonMaël和doob先生,我能够理解我所缺少的一些东西,就是我所有的3D菜鸟......我相信人们开始进入3D可能会觉得有用了回顾一下:

基本的3d概念

  • 3d Face 由一些点(顶点)和一个名为 normal 的矢量组成,表示方向面部(正面是正面,背面是哪一面)。

  • 没有法线可能非常糟糕,因为默认情况下仅在前侧应用光照。因此,当尝试应用LambertMaterial或PhongMaterial时,黑色模型。

  • OBJ文件是一种描述3D信息的方式。想要了解更多信息吗?阅读this wikipedia article (en)。此外,the french page提供了一个可用于测试的多维数据集示例。

Three.js提示和技巧

  • 当法线不存在时,无法应用光照,因此渲染黑色模型。 Three.js实际上可以使用geometry.computeVertexNormals()和/或geometry.computeFaceNormals()来计算顶点和面法线,具体取决于缺少的内容

  • 当你这样做时,有可能Three.js的正常计算错误并且你的法线将被翻转,为了解决这个问题,你可以简单地遍历几何体的面部数组:

    < / LI>
/* 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;
}

答案 1 :(得分:2)

您必须使用MeshPhongMaterial。在计算片段颜色时,MeshBasicMaterial不会考虑光线。

但是,使用MeshPhongMaterial时,网格会变黑。我从未使用过OBJ装载机,但你确定你的模型版本是正确的吗?

顺便说一句:您可能想要使用PointLight。并且它的位置应该设置为摄像机位置(light.position = camera.position应该可以做到这一点,因为它将允许在控制器编辑摄像机位置时移动灯光。)