5

我有这个对象,我正在用 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/

4

2 回答 2

9

好吧,伙计们,感谢 Maël Nison 和 doob 先生,我能够理解我所缺少的几件事,作为我完全的 3d 菜鸟......我相信开始进入 3d 的人们可能会发现一些有用的回顾:

基本 3d 概念

  • 3d由一些点(顶点)和一个称为法线的向量组成,表示面的方向(哪一侧是正面,哪一侧是背面)。

  • 没有法线可能真的很糟糕,因为默认情况下仅在正面应用照明。因此在尝试应用 LambertMaterial 或 PhongMaterial 时使用黑色模型。

  • OBJ 文件是一种描述 3D 信息的方式。想了解更多信息吗?阅读这篇维基百科文章(英文)。此外,法语页面提供了一个可用于测试的多维数据集示例。

Three.js 提示和技巧

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

  • 当你这样做时,Three.js 的法线计算可能会出错并且你的法线会被翻转,要解决这个问题,你可以简单地循环遍历几何体的 faces 数组,如下所示:

/* 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;
}
于 2012-06-22T08:54:44.727 回答
2

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

但是,当使用 MeshPhongMaterial 时,您的网格会变成黑色。我从来没有使用过 OBJ 加载器,但你确定你的模型法线是正确的吗?

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

于 2012-06-14T13:05:19.597 回答