2

私は RenderScript の限界を感じ取るための簡単なアプリケーションを作成し、三角形が約 65,000 に達すると、システムが追加の三角形をまったく描画しないことを発見しました。たとえば、70,000 個の三角形を含む円柱を作成すると、三角形の数が 65,000 を超える円柱に対応するウェッジが欠けています。三角形にはテクスチャが付けられており、アプリを簡単に作成できるTriangleMeshBuilderように、クラスを使用しただけなので、trifans や tristrips を使用するなどの実際の最適化は行われていません。ハードウェアは Samsung Galaxy Nexus です。LogCat は、約 15MB のヒープ サイズと 3% の空き領域を報告します。グラフィック システムまたは RenderScript に関するエラーや警告は表示されません。

三角形が削除された理由を説明できる人はいますか? RenderScript が正常に処理できるハードウェアの限界に達していますか?

更新は、Samsung Galaxy Nexus (4.0.3)、Samsung Galaxy Tab 7.0+ (3.2)、および Motorola Xoom (3.2) で発生します。すべて約 65,000 の三角形の同じ点にあります。これらの各デバイスには、異なる GPU が搭載されています。

更新 2 Steve Blackwell の洞察に応えて、いくつかの追加の考えがあります。

行 710-712 は実際にintインデックスをにダウンキャストするためshort、Steve が指摘するように 65536 は 0 になります。さらに、757 行目の「キャスト」は、最終的に RenderScript に送信されるバイナリ データの形式を RenderScript に伝えるほどのキャストではありません。AllocationRenderScript では、Java から RenderScript ランタイムに移行するために、すべてのデータを と呼ばれる RenderScript 固有のデータ型にパックする必要があり、データ構造について通知する必要があります。これはバグであるという Steve の意見に沿って、757 行目は RenderScript にインデックス データを次のように扱うように通知します。short(符号なし 16 ビット) しかし、32 ビットの符号付きの値を送信します (これは、チェックがないために受け入れられ、符号なしで処理され、下位 16 ビットのみが使用されるため、このしきい値と三角形を下回ると何かが描画されるのはなぜですか)行ったときに最初のインデックスに接続し直します)。

これらの値をすべて整数として受け入れてこの制限を増やすことができるかどうかを確認するためのサブクラス化TriangleMeshBuilderは機能しませんでした。これにより、アクセスできない深いコードのどこかに、unsigned short への追加の参照があると思われます。唯一の回避策は、Steve が提案するように頂点バッファーを追加することです。これは、既存のMesh.AllocationBuilderクラスで簡単に実行できます。また、これが実際にバグなのか意図的なものなのかを判断するために、デベロッパー ハングアウトで Google に報告します。

4

2 に答える 2

3

私は RenderScript についてほとんど何も知らないので、これが固有の制限なのか、ハードウェアの問題なのか、それとも TriangleMeshBuilder と関係があるのか​​ はわかりませんが、番号 65535 以降で三角形が不足していることは間違いありません。

これは符号なし 16 ビット整数の最大値であるため、マジック ナンバーです。(ウィキペディア)

コードのどこかに、unsigned short三角形の数を保持する があるのではないかと思います。Java には符号なしの値がないため、Java コードには含まれません。また、CPU レジスタ/パスウェイは 32 ビット以上であるため、制限はおそらくハードウェアではありません。だから私は TriangleMeshBuilder をチェックします。

編集:

これは553 行目の素晴らしい発見です。すべてのインデックスの値は に収まる必要がありshortます。710-712 行目でダウンキャストが発生しているようです。

私はあなたが電話していると仮定しますaddTriangle()。その関数は 3 つintの を取り、次に への明示的なキャストを行いshortます。ダウンキャストがサイレントに発生するため、これはバグだと思います。これは、関数シグネチャから期待されるものではありません。

768行目で、偽のデータが に渡されAllocation.copy1DRangeFromUnchecked()ます。私はそれを最後までたどりませんでしたが、ある時点で、これらの符号付きの値が符号なしにキャストされると想像します: -32768 から -1 は 32768 から 65535 に戻されます。しかし、それは同じデータを再解釈しているだけであり、実際には問題ではありません.

本当の問題は、65536 のような値を送信するときに始まります。65536 が にキャストされるとshort、0 に変わります。これは、実際のデータ損失です。現在、さまざまなインデックスを参照していますが、unsigned へのキャストでは修正されません。

本当のキッカーは、オーバーロードされcopy1DRangeFromUnchecked()た関数であり、オーバーロードint[]の 1 つが を受け取るため、これが問題になる必要はありませんでした。

TriangleMeshBuilder回避策として、メンバー変数mIndexData[]とメソッドをサブクラス化してオーバーライドできると思いますaddTriangle()。または、複数の頂点バッファーを使用することもできます。それともどこかにバグレポートを提出しますか? とにかく面白い問題。

于 2012-05-30T22:23:13.847 に答える
1

おそらく、OpenGL ES ではshort要素インデックスのみが許可され、int. ソース: http://duriansoftware.com/joe/An-intro-to-modern-OpenGL.-Chapter-2.1:-Buffers-and-Textures.html (「OpenGL ES」を検索)

于 2012-06-10T20:19:06.343 に答える