0

OpenGL 3.2 コードで奇妙な現象が発生しています。一連のオブジェクトを描画しています。各オブジェクトには 2D (カラー) テクスチャといくつかのかなり標準的なマテリアル設定 (拡散/鏡面反射色など) が割り当てられており、マテリアル設定をフラグメントに送信したいと考えています。均一バッファを介したシェーダ。それぞれのユニフォーム ブロックの GLSL 宣言は次のようになります。

layout(std140) uniform MaterialBlock {
    vec4 diffuseColor, specularColor;
    float shininess, ambient, emission;
} material;

そして、これは私のレンダリングサイクルが疑似コードでどのように見えるかです:

glUseProgram(objectShaderId);

for each object {

    // Set material
    glBindBuffer(GL_UNIFORM_BUFFER, materialBufferId);
    MaterialBlockPtr = glMapBuffer(GL_UNIFORM_BUFFER, GL_WRITE_ONLY);
    <set object's material values via MaterialBlockPtr>
    glUnmapBuffer(GL_UNIFORM_BUFFER);

    // Set texture
    glBindTexture(GL_TEXTURE_2D, textureId);

    // Draw
    glBindVertexArray(object.vertexArrayId);
    glDrawElements(GL_TRIANGLES, object.faceCount, GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);

}

これは、a) 1 つのオブジェクトのみが画面上にある、または b) このシェーダを使用するすべてのオブジェクトが同じマテリアル設定を共有している、または c) 他のオブジェクトが異なるシェーダを使用している限り、十分に機能します。

2 つのオブジェクトが同じシェーダーを使用しているが、異なるマテリアル設定 (たとえば、一方は青、もう一方は緑のディフューズ カラー) を持ち、両方がフレーム内にあるとすぐに、それらは狂ったようにちらつき始めます。マテリアル設定と他のオブジェクトの設定はランダムに見えます。明らかに、一部の描画は以前の呼び出しのマテリアル値が均一バッファーに残っている状態で行われますが、なぜでしょうか? ユニフォーム バッファーに関する重要な情報を見逃していませんか? glDraw* への呼び出しがバッファへの書き込みデータとオーバーラップする可能性がありますか、または glDraw* への呼び出しが行われた後にバッファの内容が画面の内容に影響を与える可能性はありますか?

記録のために、GeForce GT650M の OS X 10.7.5 でこれを開発しています。

4

1 に答える 1

1

わかりましたこれには非常に問題があると確信しています:

layout(std140) uniform MaterialBlock {
    vec4 diffuseColor, specularColor;
    float shininess, ambient, emission;
} material

マテリアル アンビエントと発光自体の色も vec4 配列として宣言されるはずだったと確信しています。描画コードには次のようなものがあると思われます。

//this is just an example and assumption
float material_ambient[4];
float material_emmission[4];
//to setup material ambient and emmissive colour
material_ambient = {1.0, 1.0, 1.0, 1.0};
material_emmision = {1.0, 1.0, 1.0, 1.0};

glUniform4f(material_ambient_id, material_ambient[0], material_ambient[1], material_ambient[2], material_ambient[3]);
glUniform4f(material_emissive_id, material_emissive[0], material_emissive[1], material_emissive[2], material_emissive[3]);

ここでの非常に明白な問題は、シェーダーの float 変数に 4 つの要素配列を送信しようとすることです...これが役立つことを願っています

于 2013-11-05T18:48:33.137 に答える