Three.js:用alpha颜色绘制大量三角形(50k +)的最佳方法

时间:2014-01-17 11:26:32

标签: javascript three.js webgl cad

我目前正在构建一个可视化CAD / CAE数据的Web应用程序。

data 

是一个包含我所有三角形的数组。

绘制三角形的第一种方法是创建一个几何体:

triangles = new THREE.Geometry();

然后将所有三角形添加到其中:

 for (var i = 0; i < data.triangles.length; i++) {
    triangles.vertices.push(new THREE.Vector3(data.triangles[i][0].x, data.triangles[i][0].y, data.triangles[i][0].z));
    triangles.vertices.push(new THREE.Vector3(data.triangles[i][1].x, data.triangles[i][1].y, data.triangles[i][1].z));
    triangles.vertices.push(new THREE.Vector3(data.triangles[i][2].x, data.triangles[i][2].y, data.triangles[i][2].z));
    triangles.faces.push(new THREE.Face3(0,1,2));
    triangles.faces[i].vertexColors[0] = new THREE.Color(0xFF0000);
    triangles.faces[i].vertexColors[0].setRGB(data.triangles[i][0].r, data.triangles[i][0].g, data.triangles[i][0].b);
    triangles.faces[i].vertexColors[1] = new THREE.Color(0x00FF00);
    triangles.faces[i].vertexColors[1].setRGB(data.triangles[i][1].r, data.triangles[i][1].g, data.triangles[i][1].b);
    triangles.faces[i].vertexColors[2] = new THREE.Color(0x0000FF);
    triangles.faces[i].vertexColors[2].setRGB(data.triangles[i][2].r, data.triangles[i][2].g, data.triangles[i][2].b);
    lvar += 3;
 }

添加材料

material = new THREE.MeshBasicMaterial({
   vertexColors: THREE.VertexColors,
   side: THREE.DoubleSide,
   transparent: true,
   opacity: .99
});

并将网格物体添加到我的场景对象中。

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

这种方法到目前为止工作正常,但因为我只使用一种材料,我不知道如何将alpha添加到我的vertexColors。

我的第二种方法是为每个三角形创建一个几何体。

for (var i = 0; i < data.triangles.length; i++) {
   triangles = new THREE.Geometry();
   triangles.vertices.push(new THREE.Vector3(data.triangles[i][0].x, data.triangles[i][0].y, data.triangles[i][0].z));
   triangles.vertices.push(new THREE.Vector3(data.triangles[i][1].x, data.triangles[i][1].y, data.triangles[i][1].z));
   triangles.vertices.push(new THREE.Vector3(data.triangles[i][2].x, data.triangles[i][2].y, data.triangles[i][2].z));
   triangles.faces.push(new THREE.Face3(0,1,2));
   triangles.faces[i].vertexColors[0] = new THREE.Color(0xFF0000);
   triangles.faces[i].vertexColors[0].setRGB(data.triangles[i][0].r, data.triangles[i][0].g, data.triangles[i][0].b);
   triangles.faces[i].vertexColors[1] = new THREE.Color(0x00FF00);
   triangles.faces[i].vertexColors[1].setRGB(data.triangles[i][1].r, data.triangles[i][1].g, data.triangles[i][1].b);
   triangles.faces[i].vertexColors[2] = new THREE.Color(0x0000FF);
   triangles.faces[i].vertexColors[2].setRGB(data.triangles[i][2].r, data.triangles[i][2].g, data.triangles[i][2].b);
   lvar += 3;
   material.triangles = new THREE.MeshBasicMaterial({
      vertexColors: THREE.VertexColors,
      side: THREE.DoubleSide,
      transparent: true,
      opacity: .99
   });
   var mesh = new THREE.Mesh(triangles, material);
   scene.add(mesh);
}

通过这种方法,我可以为每个方面的材质添加我的alpha /不透明度。

不幸的是,我用第二个方法获得了低fps。

方法1:6000个三角形=&gt; 60 fps

方法2:6000个三角形=&gt; 15 fps

有没有办法用每个面/点绘制多个三角形(> 50.000)并且仍然大约60 fps(是的,我知道它也取决于硬件)。

修改 使用Raycaster对我的项目至关重要。

编辑2:
经过一些测试后,我决定采用以下方法:
像我在第一种方法中所做的那样创建一个几何体 将MeshBasicMaterial替换为ShaderMaterial

首先我创建了两个着色器:

<script type="x-shader/x-vertex" id="vertexshader">
   attribute vec3 customColor;
   attribute float customOpacity;

   varying vec3 vColor;
   varying float vOpacity;

   void main() {
      vColor = customColor;
      vOpacity = customOpacity;
      gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
   }
</script>
<script type="x-shader/x-fragment" id="fragmentshader">
   varying vec3 vColor;
   varying float vOpacity;

   void main() {
     gl_FragColor = vec4( vColor, vOpacity);
   }
</script>

然后我用MeshBasicMaterial替换了ShaderMaterial 定义我的attributes

attributes = {
   customColor: {    type: 'c', value: [] },
   customOpacity: { type: 'f', value: []}   
};

创建/填充我的几何体,颜色和不透明度:

geometry = new THREE.Geometry();
for (var i = 0, k, lvar = 0; i < data.triangles.length; i++) {
   for (k = 0; k < 3; k++) {
      geometry.vertices.push(new THREE.Vector3(data.triangles[i][k].x, data.triangles[i][k].y, data.triangles[i][k].z));
      attributes.customColor.value[lvar + k] = new THREE.Color(THREE.ColorKeywords.black);
      attributes.customColor.value[lvar + k].setRGB(data.triangles[i][k].r, data.triangles[i][k].g, data.triangles[i][k].b);
      attributes.customOpacity.value[lvar + k] = 1.0;
   }
   geometry.faces.push(new THREE.Face3(lvar, lvar + 1, lvar + 2));
   lvar += 3;
}

创建了我的ShaderMaterial

var shaderMaterial = new THREE.ShaderMaterial({
   attributes: attributes,
   vertexShader: document.getElementById('vertexshader').textContent,
   fragmentShader: document.getElementById('fragmentshader').textContent,
   blending: THREE.NormalBlending,
   depthTest: true,
   transparent: true,
   side: THREE.DoubleSide,
   linewidth: 2
});

最后我的网格:

var mesh = new THREE.Mesh(sc.geometry.triangles, shaderMaterial);
scene.add(mesh);

0 个答案:

没有答案