2014-01-28 4 views
2

Я объединяю несколько кубов в разные формы блоков с помощью three.js, используя THREE.GeometryUtils.merge. Я хочу, чтобы эти блочные формы прозрачны, но когда он прозрачен вы можете увидеть, что это несколько кубов слипшихся, как это:Three.js, удаляющий внутренние грани

merged cubes

Как сделать мои слившиеся кубики прозрачными без рендеринга внутренних краев? (Как я удалить внутренние поверхности?)

Моего кода, который сливает кубы:

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 })); 
+0

Альтернативный подход здесь: http://stackoverflow.com/questions/23373816/remove-adjoining-faces-in-three-js/23376297#23376297 – majman

ответ

4

После нескольких экспериментов я, наконец, получил то, что хотел. Надеюсь, это поможет другим людям.

Я просматриваю каждую грань блока и raycast сам блок, используя центр тяжести лица и инвертированный нормальный (так, чтобы нормальные точки внутрь). Если он пересекается с другим лицом, которое является частью блока, мы знаем, что это лицо является внутренним лицом, и мы можем идти вперед и удалять его.

// 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 
} 
+0

Centroid был удален с лица, он выглядит. Я пытаюсь найти другое решение. –

+1

Реализована функция для работы с современными тремя (протестировано с r76 https://gist.github.com/DelvarWorld/c9c41b549d0b1e97da8890a79e3ab8d0) –

1

Вы можете фактически инициализировать каждый воспринимаемый материал кубы отдельно и индивидуально установить прозрачность внутренних граней 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 для демо

+1

спасибо за предложение! Это было не совсем то, что я искал, хотя, но я сам разработал решение. Еще раз спасибо! – Penguinator

Смежные вопросы