0

私のフラグメント シェーダーの 1 つは、基本的な OpenGL ES 1.1 マルチテクスチャリング機能の一部をエミュレートします。

その一環として、次の GLSL 関数を宣言しています。

void applyTexture(int tuIdx) {
    lowp vec4 texColor = texture2D(s_cc3Textures[tuIdx], v_texCoord[tuIdx]);
    int tuMode = u_cc3TextureUnitMode[tuIdx];

    if (tuMode == k_GL_COMBINE)
        combineTexture(texColor, tuIdx);
    else if (tuMode == k_GL_MODULATE)
        fragColor *= texColor;
    else if (tuMode == k_GL_DECAL)
        fragColor.rgb = (texColor.rgb * texColor.a) + (fragColor.rgb * (1.0 - texColor.a));
    else if (tuMode == k_GL_REPLACE)
        fragColor = texColor;
    else if (tuMode == k_GL_ADD) {
        fragColor.rgb += texColor.rgb;
        fragColor.a *= texColor.a;
    }
    else if (tuMode == k_GL_BLEND) {
        fragColor.rgb =  (fragColor.rgb * (1.0 - texColor.rgb)) + (u_cc3TextureUnitColor[tuIdx].rgb * texColor.rgb);
        fragColor.a *= texColor.a;
    }
}

k_GL_XXX定数は#definedシェーダーの上部にあります。

マルチテクスチャリングを実行するには、この関数を複数回呼び出します。iOS の SGX GPU の場合、これは for ループを使用して正常に実行されます。

for (int tuIdx = 0; tuIdx < MAX_TEXTURES; tuIdx++) {
    if (tuIdx == u_cc3TextureCount) return;     // Break out once we've applied all the textures
    applyTexture(tuIdx);
}

u_cc3TextureCountint ユニフォームで、MAX_TEXTURES#definedです2

奇妙なことに、このループを手動で展開しようとしても機能せず、何も描画されません。

if (u_cc3TextureCount > 0) {
    applyTexture(0);
}
if (u_cc3TextureCount > 1) {
    applyTexture(1);
}

さらに奇妙なことに、さらに基本的なこともできません。

applyTexture(0);
applyTexture(1);

控えめに言っても、これは完全に予期しない動作です。

u_cc3TextureCountの値がであることを確認した2ので、これら 3 つのアプローチはすべて同じ結果になるはずです。

ループを展開しようとしている理由は、一部の Android GPU を含む複数の GPU と、iPad Air の新しい Apple A7 GPU がループで正しく動作しないためです。applyTexture()すべての GPU で機能する関数を複数回呼び出す方法を見つけようとしています。

このような基本的なループ展開が機能しない理由を説明できる人はいますか?

4

0 に答える 0