GLSL シェーダーを使用して小さなレンダリング エンジンをコーディングしています。
各メッシュ (まあ、サブメッシュ) には、多数の頂点ストリーム (位置、法線、テクスチャ、接線など) が 1 つの大きな VBO と MaterialID に含まれています。
各マテリアルには一連のテクスチャとプロパティがあります (例: スペキュラー カラー、ディフューズ カラー、カラー テクスチャ、法線マップなど)。
次に、ユニフォームと属性を備えた GLSL シェーダーがあります。まあ言ってみれば:
uniform vec3 DiffuseColor;
uniform sampler2D NormalMapTexture;
attribute vec3 Position;
attribute vec2 TexCoord;
私は、GLSL シェーダーが属性とユニフォームのストリーム マッピング (セマンティクス) を定義し、頂点ストリームを適切な属性にバインドする方法を設計しようとして、少し行き詰まっています。
メッシュに言う行の何か:「位置ストリームを属性 "Position" に、tex 座標を "TexCoord" に入れます。また、マテリアルの拡散色を "DiffuseColor" に、マテリアルの 2 番目のテクスチャを "NormalMapTexture" に入れます。
現時点では、アトリビュートにハードコーディングされた名前を使用しており (つまり、頂点の位置は常に "Position" など)、各ユニフォームとアトリビュートの名前をチェックして、シェーダーがそれを何に使用しているかを理解しています。
「頂点宣言」を作成する方法を探していると思いますが、ユニフォームとテクスチャも含まれています。
だから、大規模なレンダリングエンジンでこれをどのように行うのか疑問に思っています。
編集:
提案された方法の要約:
1. 属性/Uniform セマンティックは、変数の名前によって与えられます (私が今行っていること) 可能な属性ごとに定義済みの名前を使用します。変数の名前:
//global static variable
semantics (name,normalize,offset) = {"Position",false,0} {"Normal",true,1},{"TextureUV,false,2}
...when linking
for (int index=0;index<allAttribs;index++)
{
glGetActiveAttrib(program,index,bufSize,length,size[index],type[index],name);
semantics[index]= GetSemanticsFromGlobalHardCodedList(name);
}
... when binding vertex arrays for render
for (int index=0;index<allAttribs;index++)
{
glVertexAttribPointer(index,size[index],type[index],semantics[index]->normalized,bufferStride,semantics[index]->offset);
}
2. 各セマンティックの事前定義された場所
GLSL バインダーは常に頂点配列を同じ場所にバインドします。一致する適切な名前を使用するのはシェーダー次第です。(これは方法 1 と非常によく似ていますが、誤解しない限り、シェーダーがそれを消費しなくても、利用可能なすべての頂点データをバインドすることを意味します)
.. when linking the program...
glBindAttribLocation(prog, 0, "mg_Position");
glBindAttribLocation(prog, 1, "mg_Color");
glBindAttribLocation(prog, 2, "mg_Normal");
3. マテリアル、エンジン グローバル、レンダラー、メッシュから利用可能な属性のディクショナリ
アクティブなマテリアル、エンジン グローバル、現在のレンダラー、および現在のシーン ノードによってパブリッシュされた使用可能な属性のリストを維持します。
例えば:
Material has (uniformName,value) = {"ambientColor", (1.0,1.0,1.0)}, {"diffuseColor",(0.2,0.2,0.2)}
Mesh has (attributeName,offset) = {"Position",0,},{"Normals",1},{"BumpBlendUV",2}
次にシェーダーで:
uniform vec3 ambientColor,diffuseColo;
attribute vec3 Position;
頂点データをシェーダーにバインドするとき、GLSL バインダーは属性をループし、辞書で見つかった (または見つからない?) 属性にバインドします。
for (int index=0;index<allAttribs;index++)
{
glGetActiveAttrib(program,index,bufSize,length,size[index],type[index],name);
semantics[index] = Mesh->GetAttributeSemantics(name);
}
ユニフォームと同じように、アクティブなマテリアルとグローバルのみをクエリします。