33

Three.jsは、65kを超える頂点をロードできないと言っています。

私の純粋なwebglアプリケーションでは、何も表示されませんが、大きなオブジェクトを試してみると、オブジェクト全体が表示されません。

オブジェクトを小さなバッファに分割することはできますが、それは私を悲しくさせます。

より良い解決策はありますか?65kは本当に頂点の制限量ですか?

4

7 に答える 7

42

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

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

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

于 2011-02-16T14:59:30.770 に答える
19

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

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

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

于 2011-10-04T01:24:57.063 に答える
10

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

ここで、セグメント間で共有されている頂点をワークアウトする必要があります。その場合、最も簡単な代替方法は、その頂点を複製して、共有された頂点がもう存在しないようにすることです。しかし、よりメモリに優しい代替手段があります。

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

お役に立てば幸いです;-)

于 2011-03-04T04:02:02.163 に答える
6

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

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

于 2012-11-07T02:09:14.503 に答える
5

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

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

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

于 2011-04-30T18:43:19.223 に答える
1

10年が経過し、最近のSafari 15以降、WebGL2は今ではかなり普遍的です。WebGL2は必要な情報を提供します。

gl.getParameter(GL.MAX_ELEMENT_INDEX)
gl.getParameter(GL.MAX_ELEMENTS_VERTICES)
gl.getParameter(GL.MAX_ELEMENTS_INDICES)

さらに多くの制約やその他のデータについては、こちらをご覧ください[MDN]

于 2021-12-29T02:06:59.637 に答える
-1

私の知る限り、これは通常、ハードウェアやドライバーソフトウェアによって制限されます(ハードウェアは16ビットインデックスなどを使用しています)。たぶん、Three.jsはそれを安全に再生し、webgl-appがすべてのカードで機能することを確認しようとします。おそらく最善の方法は、モデルを小さなチャンクに分割することです。これにより、アプリが現在使用されているすべてではないにしてもほとんどのGPUをサポートするようになります。

  • 即時モード(glBegin ... glEnd)を使用すると、プッシュできる頂点の数に制限はありませんが、その数の頂点では遅くなります。
  • GL_INDEX_BITS、GL_MAX_ELEMENTS_VERTICES、およびGL_MAX_ELEMENTS_INDICESでglGetIntegerv()を使用して、カード/ドライバーがサポートするインデックスビットの量、最大頂点、および最大インデックスをクエリできます。
  • 私の記憶が正しければ、頂点配列とVBO(頂点バッファーオブジェクト)はどちらも(同じカード/ドライバー上で)同様の制限があるため、それらを切り替えることはおそらく役に立ちません(これについては100%確実ではありません)
于 2011-02-15T06:04:23.603 に答える