如何渲染部分半透明网格?

时间:2017-10-19 07:55:08

标签: 3d three.js transparency

我遇到的问题是当我有一个网格,其中只有网格的一些面应该是半透明的而对象的其余部分应该是不透明的。任何人都知道我应该如何解决这个问题?

为清晰起见,这里有一些问题的更多描述:在我们的查看器中,如果它们具有相同的材料属性,我们将多个网格合并在一起。

然后,如果用户点击合并对象,我们会找到被点击的表面以及该面对象的原始id。然后我们只使用自己的自定义着色器突出显示该对象的面。

选择了一个对象为one object selected

现在的问题是,如果我们使材质透明(因此所选部分是半透明的),那么整个合并网格是透明的,模型的不透明部分将呈现为透明。

您可以在此图片中看到一些视觉问题:

部分透明对象的视觉问题
visual issues for partially transparent object

我对如何解决这个问题有很多想法,但它们都会增加内存消耗和复杂性:

  1. 丢弃应该是透明的片段,然后使用选定的面和透明材质创建一个新网格。

  2. 创建透明的整个合并网格的副本,然后仅渲染透明对象中的选定对象面,并丢弃原始非透明网格中的碎片。

  3. 有人有更好的主意吗?

    使用三个r84。

1 个答案:

答案 0 :(得分:0)

我无法理解为什么你不想使用分离的盒子网格,因为管理每个网格的透明度会更容易。

但是如果你想使用单个几何体,我想出了一种使用两种材质.materialIndex和动态几何体的方法。该方法依赖于this SO answer

var materials = [
  new THREE.MeshLambertMaterial({ color: "white" }),
  new THREE.MeshLambertMaterial({ color: "white", transparent: true, opacity: 0.5})
];

. . .

var cloneGeom = new THREE.Geometry();

var oldBoxIndex = 0;

function setBoxTransparent(boxIndex) {
  cloneGeom = mesh.geometry.clone();
  setBoxMaterial(oldBoxIndex, 0);
  setBoxMaterial(boxIndex, 1);
  mesh.geometry.dispose();
  mesh.geometry = cloneGeom;
  oldBoxIndex = boxIndex;
}

function setBoxMaterial(boxIndex, materialIndex) {
  for (let i = 0; i < 12; i++) {
    cloneGeom.faces[12 * boxIndex + i].materialIndex = materialIndex;
  }
}

jsfiddle示例r87。