7

モデル、マテリアル、ライトなど、通常の 3D のものを処理するために C++ でコードを書いています。たとえば、マテリアルに均一な変数を設定するには、シェーダーからそれらのハンドルを知る必要があります。メッシュをメモリにロードするには、さまざまな場所へのハンドルを知る必要がありinます。

モデル、マテリアルなどにはそれぞれシェーダーへのハンドルがあり、 のようなことができるようglUniform1f(shader->getKdLocation(),kd)になりましたが、この種のホットポテトは私には悪いデザインのようです。ユニフォームとインとアウトがシェーダーでハードコードされており (例: レイアウト = 0)、.. でバインドされているチュートリアルを見てきましたglUniform1f(0,kd)。ただし、これは、コードの残りの部分が特別にレイアウトされたシェーダーでのみ機能することを意味するため、次善のソリューションのように思えます。また、サブルーチンに対してこれを行うことはできないと思います。これにより、これは一貫性のないオプションになります。

すべてがシェーダー リファレンスを取得するか、場合によってはシェーダー リファレンスがないと適切にインスタンス化できないか (メッシュなど)、またはより多くの場所で数値をハードコーディングするか、ハードコーディングに伴う問題に対処する必要があるかの選択のようです。

これらのモデル、ライトなどを独立してライブ/動作させ、シーンのシェーダーを設定したときにのみ「機能」できるようにする必要がありますが、これを行うための確実な方法を見つけることができないようです. 私の結論の質問は、シェーダーを処理するためのベストプラクティスは何ですか? すべての問題が解決されなくても問題ありません。適切な設計上の決定とは何か、またその理由を知りたいだけです。

4

2 に答える 2

1

問題はエンジン アーキテクチャか、それとも不足です。多くのゲーム エンジンでは、ゲーム オブジェクトは、ジオメトリを処理するメッシュ オブジェクト (頂点バッファなど)、マテリアル オブジェクト (メッシュ オブジェクトの外観を担当) などのいくつかのカテゴリに分類されます。このようなデザインのマテリアルは、通常、レンダリング中にシェーダーに渡されるユニフォームの情報を含むエンティティです。このようなデザインでは、再利用したり、異なるレンダリング可能なオブジェクト間で異なるマテリアルを再割り当てしたりできるため、かなりの柔軟性が得られます。特定のシェーダー プログラムを特定のマテリアル タイプに設定できるため、メッシュが描画されるたびに、そのマテリアルがシェーダー プログラムと相互作用し、必要なすべてのユニフォームが渡されます。

オープンソースの OpenGL エンジンを調べて、その仕組みを理解することをお勧めします。

于 2013-07-31T20:19:45.497 に答える
0

クライアントのユニフォームの仕様と、シェーダーに配置された実際のユニフォームの場所との間の関連性が緩いことに関しても、同じ懸念がありました。

できる 1 つの方法は、 glGetUniformLocationを使用して、その名前に基づいて一様変数の場所を決定することです。まだ完璧ではないかもしれませんが、おそらくこれが最善の方法です。

例:

// Old way:
GLfloat myfloat = ...;
glUniform1f(0, myfloat);   // Hope that myfloat was supposed to go at location 0...

// Slightly better...
GLfloat myfloat = ...;
GLint location = glGetUniformLocation(myprogram, "myfloat");
glUniform1f(location, myfloat);   // We know that a uniform with name "myfloat" goes at this location

glGetActiveUniformを使用したいくつかの追加作業により、「myfloat」が期待どおりのタイプ/サイズ/その他を持っていることを確認することもできます。

于 2013-08-01T12:25:12.610 に答える