8

three.js を使用してインタラクティブなデータ視覚化を作成しています。このビジュアライゼーションには、68000 個のノードのレンダリングが含まれます。各ノードは、サイズと色が異なります。

最初はメッシュをレンダリングしてこれを行おうとしましたが、非常にコストがかかることがわかりました。私の現在の試みは、各ポイントが視覚化のノードである three.js パーティクル システムを使用することです。

ポイントの色 * サイズを制御できますが、特定のポイントまでしか制御できません。私のカードでは、GL ポイントの最大サイズは 63 のようです。ビジュアライゼーションを拡大すると、ポイントが大きくなり、ポイントになり、63 ピクセルのままになります。

現在、頂点とフラグメントのシェーダーを使用しています:

頂点シェーダー:

attribute float size;
attribute vec3 ca;
varying vec3 vColor;

void main() {
    vColor = ca;
    vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );
    gl_PointSize = size * ( 300.0 / length( mvPosition.xyz ) );
    gl_Position = projectionMatrix * mvPosition;
}

フラグメント シェーダー:

uniform vec3 color;
uniform sampler2D texture;

varying vec3 vColor;

void main() {
    gl_FragColor = vec4( color * vColor, 1.0 );
    gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );
}

これらは、three.js の例の 1 つからほぼそのままコピーされています。

GLSL はまったく初めてですが、63 ピクセルを超えるポイントを描画する方法を探しています。特定のサイズよりも大きいポイントのメッシュを描画するようなことはできますか?それ以外の場合は gl_point を使用できますか? 63 ピクセルより大きいポイントを描画するために使用できる他の回避策はありますか?

4

2 に答える 2

6

単位クワッド + 中心点の配列を作成し、GLSL でサイズを拡張することで、独自のポイント システムを作成できます。

したがって、2 つのバッファがあります。1 つのバッファーは、描画するポイントの数だけ繰り返される 2D unitQuad です。

var unitQuads = new Float32Array([
  -0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5,
  -0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5,
  -0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5,
  -0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5,
  -0.5, 0.5, 0.5, 0.5, -0.5, -0.5, 0.5, -0.5,
];

2 つ目は、位置をそれぞれ 4 回繰り返す必要があることを除いて、あなたのポイントです。

var points = new Float32Array([
  p1.x, p1.y, p1.z, p1.x, p1.y, p1.z, p1.x, p1.y, p1.z, p1.x, p1.y, p1.z,
  p2.x, p2.y, p2.z, p2.x, p2.y, p2.z, p2.x, p2.y, p2.z, p2.x, p2.y, p2.z,
  p3.x, p3.y, p3.z, p3.x, p3.y, p3.z, p3.x, p3.y, p3.z, p3.x, p3.y, p3.z,
  p4.x, p4.y, p4.z, p4.x, p4.y, p4.z, p4.x, p4.y, p4.z, p4.x, p4.y, p4.z,
  p5.x, p5.y, p5.z, p5.x, p5.y, p5.z, p5.x, p5.y, p5.z, p5.x, p5.y, p5.z,
]);

バッファと属性を設定する

var buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, unitQuads, gl.STATIC_DRAW);
gl.enableVertexAttribArray(unitQuadLoc);
gl.vertexAttribPointer(unitQuadLoc, 2, gl.FLOAT, false, 0, 0);

var buf = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buf);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
gl.enableVertexAttribArray(pointLoc);
gl.vertexAttribPointer(pointLoc, 3, gl.FLOAT, false, 0, 0);

GLSL シェーダーで必要な gl_PointSize を計算し、ビュー スペースまたはスクリーン スペースで unitQuad にそのサイズを掛けます。スクリーン スペースは gl_Point が行うものと一致しますが、多くの場合、通常のもののようにポイントを 3D で拡大縮小したい場合、ビュー スペースが必要です。

attribute vec2 a_unitQuad;
attribute vec4 a_position;
uniform mat4 u_view;
uniform mat4 u_viewProjection;

void main() {
   float fake_gl_pointsize = 150;

   // Get the xAxis and yAxis in view space
   // these are unit vectors so they represent moving perpendicular to the view.
   vec3 x_axis = view[0].xyz;
   vec3 y_axis = view[1].xyz;

   // multiply them by the desired size 
   x_axis *= fake_gl_pointsize;
   y_axis *= fake_gl_pointsize;

   // multiply them by the unitQuad to make a quad around the origin
   vec3 local_point = vec3(x_axis * a_unitQuad.x + y_axis * a_unitQuad.y);

   // add in the position you actually want the quad.
   local_point += a_position;

   // now do the normal math you'd do in a shader.
   gl_Position = u_viewProjection * local_point;
}

それが意味を成したかどうかはわかりませんが、もっと複雑ですが、実際のサンプルがここにあります

于 2013-03-14T19:45:20.987 に答える
2

特定のサイズよりも大きいポイントのメッシュを描画するようなことはできますか?それ以外の場合は gl_point を使用できますか?

WebGL にはありません。

パーティクル システムを一連の四角形 (つまり、2 つの三角形) として描画できます。しかし、それはそれについてです。

于 2013-03-12T21:17:55.237 に答える