web-dev-qa-db-ja.com

WebGLの頂点に制限はありますか?

Three.jsによると、65kを超える頂点をロードすることはできません。私の純粋なwebglアプリケーションでは、何も表示されませんが、大きなオブジェクトを試してみると、オブジェクト全体が表示されません。

オブジェクトを分割して小さなバッファに入れることを考えていますが、それは私を悲しくさせます。より良い解決策はありますか? 65kは本当に頂点の制限量ですか?

30
zVictor

はい、現在WebGLの頂点インデックスバッファは16ビットに制限されています。これは、バージョン1.0を可能な限りクロスプラットフォームにすることを目指しているためです。そのため、このような場合、グラフィックハードウェアが制限されたモバイルプラットフォームなど、最小公分母をターゲットにする傾向があります。

1.0がリリースされ、最初のRushが終了すると、拡張機能を使用してこれらの制約を緩和する可能性があります。アプリは、特定の拡張機能が実装でサポートされているかどうかを確認し、サポートされている場合はそれを利用できます。通常のデスクトップOpenGLと同じです。すでにいくつかの拡張機能が利用可能ですが、ここでも非常に幅広いハードウェアサポートを備えた拡張機能しか許可されていないため、頂点数を増やすのに役立つものは何もありません。ただし、クロスプラットフォームの要件を緩和すると、32ビットの頂点インデックスを許可するGL_OES_element_index_uint拡張機能などをサポートする可能性があります。

パブリックWebGLメーリングリストでのこれらの問題に関するいくつかの議論 を読むことができます。

39
Giles Thomas

一般的に他の答えは正しいですが、私は少し説明を追加すると思いました:

WebGL(およびOpenGL ES 2.0)でインデックスとして受け入れられるデータ型は、符号なしバイトと符号なしショートのみです。 unsigned shortの範囲は0〜65535であるため、これは、gl.DrawElements(ほとんどのフレームワークが使用)を使用している場合、描画呼び出しごとに参照できる頂点は65kのみであることを意味します。これはほぼ間違いなく、three.jsの制限の原因です。 65kの頂点しか共有しない限り、1回の描画呼び出しで65kをはるかに超える可能性があることに注意してください三角形

インデックス付けされていないジオメトリ(gl.DrawArrays)を使用する場合、呼び出しごとにより多くの頂点を持つことができますが、ほとんどの場合、それらのいくつかを繰り返す必要があることに注意してください。ほとんどの場合、GPUメモリ使用量の削減は、描画呼び出しを分割することを正当化すると思います。

17
Toji

今のところ、あなたができることは、大きなオブジェクトをそれぞれ65K要素のいくつかのセグメントに分割し、すべてのセグメントに0から65Kのインデックスが付けられるようにすべてのセグメントにインデックスを付け直すことです。私はそれをテストしました、そして、WebGLはそれを許可します。

ここで、セグメント間で共有されている頂点をトレーニングする必要があります。その場合、最も簡単な代替方法は、その頂点を複製して、共有頂点が存在しないようにすることです。しかし、より多くのメモリフレンドリーの選択肢があります。

私はこの動作の小さなデモを持っています(5つのセグメントに分割された約350Kの頂点を持つ脳モデル) http://youtu.be/AXZiNHkMpZs#t=2m33s

私はそれが役立つことを願っています;-)

8
Diego

Gilesにコメントできないので、このコメントをここに置きます。

OES_element_index_uintが「コミュニティ承認済みWebGL拡張機能」に追加されました!!拡張機能はchrome canary。 http://www.khronos.org/registry/webgl/extensions/OES_element_index_uint/ ですでに有効になっています

5
Kaj Dijkstra

drawElements(インデックスの配列を頂点の配列にトラバースする)またはdrawArrays(頂点の配列を直接トラバースする)のいずれかを使用して頂点を描画できます。

drawArraysを使用する場合、属性バッファー内の頂点の数に制限はないようです。通常のメッシュでは、プリミティブに表示されるたびに各頂点を指定する必要があるため、drawArraysを使用することはあまり望ましくありません。一方、シーンによっては、これはWebGL呼び出しの数を減らす簡単な方法かもしれません。

この質問とその受け入れられた回答を読んだ後、私は長い間、drawArraysの頂点の数も65Kに制限されていると思っていたのでこれについて言及します。偶然、そうではないことに気づき、共通のマテリアルを持つオブジェクトを単一の頂点配列に集約することで大幅な高速化を実現しました(したがって、現在ANGLEの実装に負担をかけているように見えるバッファごとのパフォーマンスのオーバーヘッドを回避できます)。

3
brainjam