【问题标题】:Three.js removing inner facesThree.js 去除内面
【发布时间】:2014-01-30 09:29:43
【问题描述】:

我正在使用three.js 使用THREE.GeometryUtils.merge 将多个立方体合并成不同的块形状。我想让这些块形状透明,但是当它透明时你可以看到它是多个立方体像这样粘在一起:

如何在不渲染内部边缘的情况下使合并的立方体透明? (如何去除内面?)

我合并立方体的代码:

geometry = new THREE.CubeGeometry(STEP_SIZE, STEP_SIZE, STEP_SIZE);
for (i = 0; i < shape.length; i++) {
    tmpGeometry =  new THREE.Mesh(new THREE.CubeGeometry(STEP_SIZE, STEP_SIZE, STEP_SIZE));
    tmpGeometry.position.x = STEP_SIZE * shape[i].x;
    tmpGeometry.position.y = STEP_SIZE * shape[i].y;
    THREE.GeometryUtils.merge(geometry, tmpGeometry);
}

block = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({ color: 0x0000ff, opacity: 0.5, transparent: true }));

【问题讨论】:

标签: javascript 3d three.js


【解决方案1】:

经过一番试验,我终于得到了我想要的。希望这对其他人有所帮助。

我遍历块的每个面并使用面的质心和反转法线对块本身进行射线投射(使法线指向内)。如果它与块中的另一个面相交,我们知道该面是一个内面,我们可以继续删除它。

// block is a Three.Mesh object
function removeInternalFaces(block) {
    var geometry = block.geometry;
    var face;
    var toDelete = [];
    var blockRaycaster = new THREE.Raycaster();

    // raycast itself from the center of each face (negated normal), and whichever face gets intersected
    // is an inner face
    for (i = 0; i < geometry.faces.length; i++) {
        face = geometry.faces[i];
        if (face) {
            normal = face.normal.clone();
            normal.negate();
            blockRaycaster.set(face.centroid, normal);
            intersects = blockRaycaster.intersectObject(block);
            for (j = 0; j < intersects.length; j++) {
                toDelete.push(intersects[j].faceIndex);
            }
        }
    }

    // actually delete them
    for (i = 0; i < toDelete.length; i++) {
        delete geometry.faces[toDelete[i]];
    }
    geometry.faces = geometry.faces.filter( function(v) { return v; });
    geometry.elementsNeedUpdate = true; // update faces
}

【讨论】:

【解决方案2】:

您实际上可以分别初始化立方体的每个面材质,并单独将内面的不透明度设置为0。代码将是这样的。

    var materialArray = [];

        materialArray.push(new THREE.MeshLambertMaterial({
            opacity:0,
            color:0x0000FF,
            transparent: true
        }));// assuming you want this face to be transparent 
        materialArray.push(new THREE.MeshLambertMaterial({
            opacity:0,
            color:0x0000FF,
            transparent: true
        }));// assuming you want this face to be transparent
        materialArray.push(new THREE.MeshLambertMaterial({
            opacity:0.5,
            color:0x0000FF,
            transparent: true
        }));
        materialArray.push(new THREE.MeshLambertMaterial({
            opacity:0.5,
            color:0x0000FF,
            transparent: true
        }));
        materialArray.push(new THREE.MeshLambertMaterial({
            opacity:0.5,
            color:0x0000FF,
        transparent: true
        }));
        materialArray.push(new THREE.MeshLambertMaterial({
            opacity:0.5,
            color:0x0000FF,
            transparent: true
        }));
        var CubeMat = new THREE.MeshFaceMaterial(materialArray);

然后像这样将它传递给你的立方体网格。

block = new THREE.Mesh(geometry,CubeMat )

查看此JsFiddle 以获取演示

【讨论】:

  • 感谢您的建议!不过,这并不是我想要的——但我自己想出了一个解决方案。再次感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-09
  • 2013-03-23
  • 1970-01-01
  • 2013-03-24
  • 1970-01-01
  • 2015-03-05
相关资源
最近更新 更多