3

2 つのサーフェスを考慮した屈折シェーダーを作成しています。そのため、FBO を使用して深度と法線をテクスチャにレンダリングし、キューブマップを使用して環境を表現しています。背面の屈折法線を取得するために、テクスチャに保存されている法線の値を使用してキューブマップから値をフェッチする必要があります。

キューブマップは、値がテクスチャから取得されたベクトルからアクセスしようとしない限り、完全に機能します。

以下は、失敗する最小限のフラグメント シェーダーです。色は必死に黒のままです。texture 2D の呼び出しがゼロ以外の値を返すことは確かです。方向に含まれるテクスチャ カラー (法線を表す) を表示しようとすると、完全に色付けされたモデルが得られます。「方向」ベクトルでどのような操作を行っても、失敗し続けます。

uniform samplerCube cubemap;
uniform sampler2D normalTexture;
uniform vec2 viewportSize;

void main()
{
   vec3 direction = texture2D(normalTexture, gl_FragCoord.xy/viewportSize).xyz;
   // direction = vec3(1., 0., 0) + direction; // fails as well!!
   vec4 color = textureCube(cubemap, direction);
   gl_FragColor = color;
}

色として表示されるベクトル「方向」の値は、null ではないことの証明にすぎません! の値 そして、これが上記のシェーダーの結果です (ティーポットのみ)。 ここに画像の説明を入力

このコードは完全に機能しますが、次のようになります。

uniform samplerCube cubemap;
uniform vec2 viewportSize;
varying vec3 T1;

void main()
{
   vec4 color = textureCube(cubemap, T1);
   gl_FragColor = color;
}

ここに画像の説明を入力

サンプラー キューブの値にアクセスするたびに色が黒のままになる理由が思いつきません。

完全を期すために、私のキューブマップは機能しますが、セットアップに使用するパラメーターを次に示します。

glEnable(GL_TEXTURE_CUBE_MAP);
glBindTexture(GL_TEXTURE_CUBE_MAP, mTextureId);
// Set parameters
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

どこかで重要なことを見逃していない限り、ドライバーのバグである可能性があると思います。グラフィック カードはありません。Intel Core i5 プロセッサ チップセットを使用しています。

00:02.0 VGA compatible controller: Intel Corporation 2nd Generation Core Processor Family Integrated Graphics Controller (rev 09)

なぜこれが発生するのか、または回避策がありますか?

編集:シェーダークラスがテクスチャをバインドする方法は次のとおりです

4 textures to bind
Bind texture 3 on texture unit unit 0
Bind to shader uniform: 327680
Bind texture 4 on texture unit unit 1
Bind to shader uniform: 262144
Bind texture 5 on texture unit unit 2
Bind to shader uniform: 393216
Bind texture 9 on texture unit unit 3
Bind to shader uniform: 196608

テクスチャ 3 と 4 は深度、5 は法線マップ、9 はキューブマップです。

そしてバインディングを行うコード:

void Shader::bindTextures() {
    dinf << m_textures.size() << " textures to bind" << endl;
    int texture_slot_index = 0;
    for (auto it = m_textures.begin(); it != m_textures.end(); it++) {
        dinf << "Bind texture " << it->first<< " on texture unit unit "
                << texture_slot_index << std::endl;
        glActiveTexture(GL_TEXTURE0 + texture_slot_index);
        glBindTexture(GL_TEXTURE_2D, it->first);
        // Binds to the shader
        dinf << "Bind to shader uniform: " << it->second << endl;
        glUniform1i(it->second, texture_slot_index);
        texture_slot_index++;
    }
    // Make sure that the texture unit which is left active is the number 0
    glActiveTexture(GL_TEXTURE0);

}

m_textures は、テクスチャ ID から均一 ID へのマップです。

4

2 に答える 2

5

法線マップとキューブマップに別々のテクスチャ ユニットを使用しているようには見えません。すべてがテクスチャ ユニット 0 にデフォルト設定されています。次のようなものが必要です。

uniform sampler2D norm_tex;

uniform samplerCube cube_tex;

シェーダーで。texture(3.2+) コア プロファイルを使用する場合、テクスチャ ルックアップは「オーバーロード」機能を使用する必要があります。(3.3+) では、サンプラー オブジェクトも使用できます。

テクスチャを生成して個別のテクスチャ ユニットにバインドします。

... generate 'norm_tex' and 'cube_tex' ...

glActiveTexture(GL_TEXTURE0);
... bind 'norm_tex' and set parameters ...

glActiveTexture(GL_TEXTURE1);
... bind 'cube_tex' and set parameters ...

... glUseProgram(prog); ...

glUniform1i(glGetUniformLocation(prog, "norm_map"), 0);
glUniform1i(glGetUniformLocation(prog, "cube_map"), 1);
于 2013-04-03T06:09:31.837 に答える
0

私はそれを理解しました、本当にばかげたことです。キューブマップを GL_TEXTURE_CUBE_MAP としてバインドするようにシェーダー関数を変更するのを忘れていました。すべてが GL_TEXTURE_2D としてバインドされていました!

とにかくありがとう!

于 2013-04-03T15:50:04.883 に答える