合并几何,但使用单一材质

时间:2016-08-26 18:24:43

标签: three.js

一般来说,Three.js和3d库有点新鲜。

我使用以下代码合并了两个几何(四分之一圆柱和一个平面):

  var planeGeo = new THREE.PlaneGeometry(planeW, planeD / 2, 199, 399);
  var planeMesh = new THREE.Mesh(planeGeo);
  planeMesh.updateMatrix();

  var cylinderGeo = new THREE.CylinderGeometry(100, 100, planeW, 199, 399, true, 0, Math.PI / 2);
  cylinderGeo.rotateZ(Math.PI / 2).translate(0, 200, -100);
  var cylinderMesh = new THREE.Mesh(cylinderGeo);
  cylinderMesh.updateMatrix();

  var singleGeometry = new THREE.Geometry();
  singleGeometry.merge(planeMesh.geometry, planeMesh.matrix);
  singleGeometry.merge(cylinderMesh.geometry, cylinderMesh.matrix);

  var testmaterial = new THREE.MeshPhongMaterial({ color: 0x666666 });
  mesh = new THREE.Mesh(singleGeometry, testmaterial);
  scene.add(mesh);

Merged geometries

然后我想在整个事情上使用单一材料(png)。此代码不起作用:

textureLoader.load('data/test.png', function (texture) {
  material = new THREE.MeshLambertMaterial({
    map: texture
  });
});

稍后在合并的块中......

mesh = new THREE.Mesh(singleGeometry, material);
scene.add(mesh);

这导致:

Merged geometries, but material doubled

我希望最终结果是整个合并几何体上的单个叠加png,但我找不到任何暗示这是正常事情的事情。有没有比合并几何形状更好的方法来实现这个结果?或者我只是在错误的地方寻找?

1 个答案:

答案 0 :(得分:1)

使用帖子中提供的形状实现此目的的穷人解决方案如下: https://jsfiddle.net/87wg5z27/44/

使用此答案中的代码:https://stackoverflow.com/a/20774922/4977165 它根据几何的边界框设置UV,省略z坐标(= 0)。这就是为什么纹理在顶部有点拉伸,你可以手动纠正它或者它可能足够你。

geometry.computeBoundingBox();

var max = geometry.boundingBox.max,
    min = geometry.boundingBox.min;
var offset = new THREE.Vector2(0 - min.x, 0 - min.y);
var range = new THREE.Vector2(max.x - min.x, max.y - min.y);
var faces = geometry.faces;

geometry.faceVertexUvs[0] = [];

for (var i = 0; i < faces.length ; i++) {

  var v1 = geometry.vertices[faces[i].a], 
      v2 = geometry.vertices[faces[i].b], 
      v3 = geometry.vertices[faces[i].c];

  geometry.faceVertexUvs[0].push([
      new THREE.Vector2((v1.x + offset.x)/range.x ,(v1.y + offset.y)/range.y),
      new THREE.Vector2((v2.x + offset.x)/range.x ,(v2.y + offset.y)/range.y),
      new THREE.Vector2((v3.x + offset.x)/range.x ,(v3.y + offset.y)/range.y)
  ]);
}
geometry.uvsNeedUpdate = true;