私のフラグメント シェーダーの 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_cc3TextureCount
int ユニフォームで、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 で機能する関数を複数回呼び出す方法を見つけようとしています。
このような基本的なループ展開が機能しない理由を説明できる人はいますか?