1

ユーザーが以前に選択したいくつかのオプションに応じて、100から2500の三角形の面を持つ中規模から大規模のオブジェクトを描画しています。オブジェクト自体は固定されています。移動せず、変換も行われず、何も行われません。これまでのところ、「私のアプリがOBJファイルをロードし、ユーザーがそれらを見る」と考えることができますが、それは間違いではありません。

トリッキーな点は、いつでもオブジェクトの一部の面が「選択」され、一部は選択されないことです。選択した面は、異なるテクスチャで表示する必要があります。同じUV座標ですが、ピクセルの色は異なるビットマップから取得されます。いつでも顔の約半分が選択され、どの顔が継続的に変更されます。

したがって、フラグメントシェーダー内で、選択した面で作業している場合は、このビットマップでtexture2D()を呼び出し、選択されていない三角形を使用している場合は、それを使用します。ただ、フラグメントシェーダーから自分がどの三角形に入っているかを見つける方法がわかりません。私の質問はどれですか:私はこれを知ることができますか?

私には別の方法があります-頂点の独自のコピーですべての面を設定し、テクスチャビットマップのサイズを2倍にし、「選択された」または「選択解除された」部分を指すように面ごとの頂点にUV座標を設定しますビットマップの数ですが、頂点の数は6倍になり、フレームごとにまったく新しいUV配列をGPUに渡します。小さいオブジェクトでも、著しく遅くなります。良くない。

4

1 に答える 1

3

フラグメント シェーダーは、それがどの三角形にあるかを認識しません。ただし、追加の頂点属性を使用することで、必要な効果を得ることができます。

残念ながら、これは通常、ハード折り目を行う場合と同じように、三角形ごとに頂点データを複製する必要があることを意味します。少なくとも他の種類の折り目を使用する必要がある場合は、別の方法で行う簡単な方法はありませ。選択の。
ただし、個別のストリームを使用すると、フレームごとにその 1 つのアトリビュートをアップロードするだけで済み、残りは一定です。その限りでは、帯域幅に関してはかなり許容範囲です。

次に、フラグメント シェーダーは両方のテクスチャを静的にサンプリングし、特別な頂点属性が 1.0 か 0.0 かに基づいて、いずれかの値を選択します (これは、分岐して毎回異なるテクスチャをサンプリングするよりも効率的であり、とにかく両方のテクスチャをサンプリングする可能性があります)。 . これにはmix組み込み関数 (通常はネイティブの 1 サイクル命令が 1 つになる) または三項演算子を使用できます。

頂点データの複製を必要としない選択の一部のサブセットの一種の有効な代替手段は、1.0 でカットオフするアトリビュートでステップ関数を使用することです。頂点の複製を必要とする問題は補間です。
1 つの頂点属性が 0 の場合、任意のフラグメント (「1.0」の頂点の真下にあるフラグメントを除く) の補間値は、必ず 1.0 未満になります。一方、「0.0」頂点の下、または 2 つの「0.0」頂点間の線上にあるフラグメント以外のフラグメントはゼロではありません。これはすべての任意の選択で機能するわけではありませんが、多くの場合、頂点データを複製せずに「ゼロ以外のものを選択する」(またはその逆) などの戦略を使用すると機能する場合があります。

ARB_provoking_vertex があれば生活は楽になりますが、残念ながら、それを提供する ES 2.0 実装はありません。

于 2012-10-06T16:54:16.600 に答える