0

WebGL で多面体をレンダリングしていますが、頂点の位置と法線を生成する、より効率的でエラーが発生しにくい方法があるかどうか疑問に思っています。

理想的には、インデックスのみを含むバッファーを GPU に送信し、頂点シェーダーで頂点ごとの位置と法線を計算します。頂点シェーダーは次のようになります。

uniform mat4 transform;

uniform ??? polyhedra; // some kind of representation of the polyhedra type    

attribute int index;

varying vec4 normal;
varying vec2 uv;

vec3 calculatePosition() { /* mathemagic w/index and polyhedra */ };
vec3 calculateNormal  () { /* mathemagic w/index and polyhedra */ };
vev2 calculateUV      () { /* mathemagic w/index and polyhedra */ };

void main() {
  gl_Position = transform * vec4(calculatePosition(), 1.0);
  normal      = transform * vec4(calculateNormal(), 1.0);
  uv          = calculateUV();
}

次に、頂点インデックスの配列を に送信しますindex。フラットシェーディングで面ごとに2つの三角形でレンダリングされた立方体の場合(法線は面ごとに異なるため、異なる面間で頂点を共有できないことを意味するため重要です)、インデックスのバッファを送信します[0.. 36) (6 つの辺 * 2 つの三角形 * それぞれ 3 つの頂点)。

これは、英雄的な努力なしに効率的に可能でしょうか?

WebGL は基本的に OpenGL ES 2.0 であるため、ジオメトリ シェーダーはありません。

4

1 に答える 1

0

確かに、これは可能ですが、おそらく実用的ではありません。

頂点を生成することはできませんが、頂点シェーダーを使用して、少なくともプロシージャルに値を入力することはできます。1 つの方法として、FBO を使用してフラグメント シェーダーで位置を計算し、頂点シェーダーを使用してテクスチャ ルックアップを使用して位置/法線/UV をフェッチすることが考えられます。OpenGL ES 2.0 にはデータを永続的に保存するための変換フィードバックがないため、これが最善の方法です。

ただし、これらの多面体を 1 回だけ生成する場合、そもそも GPU にオフロードするインセンティブはほとんどありません。WebGL はさまざまなデバイスで実行され、一部のデバイスは他のデバイスよりもスループットが高くなります。ただし、すべての場合において、頂点バッファーから頂点位置を読み取る方が、テクスチャ ルックアップよりも高速です。WebGL に変換フィードバックがあれば、別の方法を提案するかもしれませんが、これは膨大な時間の無駄のように思えます。

于 2013-09-08T22:03:06.073 に答える