【问题标题】:Very slow fract operation on Galaxy SII and SIIIGalaxy SII 和 SIII 上的非常慢的分数运算
【发布时间】:2023-04-06 00:37:02
【问题描述】:

我的地形使用着色器,它本身使用四种不同的纹理。它在 windows 和 linux 机器上运行良好,但在 android 上它在两个星系上都只有 ~25FPS。我认为,纹理是问题,但不是,因为看起来问题在于我划分纹理坐标并使用 frac 获取平铺坐标的部分。没有它,我得到 60FPS。

// Material data.
//uniform vec3 uAmbient;
//uniform vec3 uDiffuse;

//uniform vec3 uLightPos[8];
//uniform vec3 uEyePos;
//uniform vec3 uFogColor;
uniform sampler2D terrain_blend;
uniform sampler2D grass;
uniform sampler2D rock;
uniform sampler2D dirt;

varying vec2 varTexCoords;
//varying vec3 varEyeNormal;
//varying float varFogWeight;

//------------------------------------------------------------------
//  Name: fog
//  Desc: applies calculated fog weight to fog color and mixes with
//  specified color.
//------------------------------------------------------------------
//vec4 fog(vec4 color) {
//  return mix(color, vec4(uFogColor, 1.0), varFogWeight);
//}

void main(void)
{
    /*vec3 N = normalize(varEyeNormal);
    vec3 L = normalize(uLightPos[0]);
    vec3 H = normalize(L + normalize(uEyePos));

    float df = max(0.0, dot(N, L));
    vec3 col = uAmbient + uDiffuse * df;*/

    // Take color information from textures and tile them.
    vec2 tiledCoords = varTexCoords;
    //vec2 tiledCoords = fract(varTexCoords / 0.05); // <========= HERE!!!!!!!!!
    //vec4 colGrass = texture2D(grass, tiledCoords);
    vec4 colGrass = texture2D(grass, tiledCoords);
    //vec4 colDirt = texture2D(dirt, tiledCoords);
    vec4 colDirt = texture2D(dirt, tiledCoords);
    //vec4 colRock = texture2D(rock, tiledCoords);
    vec4 colRock = texture2D(rock, tiledCoords);
    // Take color information from not tiled blend map.
    vec4 colBlend = texture2D(terrain_blend, varTexCoords);
    // Find the inverse of all the blend weights.
    float inverse = 1.0 / (colBlend.r + colBlend.g + colBlend.b);
    // Scale colors by its corresponding weight.
    colGrass *= colBlend.r * inverse;
    colDirt *= colBlend.g * inverse;
    colRock *= colBlend.b * inverse;

    vec4 final = colGrass + colDirt + colRock;

    //final = fog(final);
    gl_FragColor = final;
}

注意:还有一些用于光计算和雾的代码,但未使用。我指出了未注释时会导致大量滞后的行。我尝试使用地板并手动计算小数部分,但滞后是相同的。可能有什么问题?

编辑:这就是我不明白的地方。

这个:

vec2 tiledCoords = fract(varTexCoords * 2.0);

运行良好。

这个:

vec2 tiledCoords = fract(varTexCoords * 10.0);

在 SIII 上运行平均。

这个:

vec2 tiledCoords = fract(varTexCoords * 20.0);

滞后...

这个:

vec2 tiledCoords = fract(varTexCoords * 100.0);

嗯 5FPS 还是比我预想的好...

那是什么?为什么会这样?据我了解,这不应该有任何区别。但确实如此。还有一个巨大的。

【问题讨论】:

  • 您是否尝试过删除varTexCoords / 0.05 部分并仅将其替换为varTexCoords?此外,您可以将其更改为 varTexCoords * 20.0
  • 这是我尝试的第一件事,将除法改为乘法并没有改变任何东西。
  • 我猜这不是fract 调用,而是导致延迟的纹理查找。毕竟,您正在使用四种不同纹理的四种纹理查找。现在,如果发生这种情况,texture2D 设法用varTexCoords * 2.0varTexCoords * 10.0 更好地缓冲纹理,与指责一个简单的fract 调用相比(对我来说)更有意义。但我当然是猜的。
  • 如果我修改代码只使用一种草纹理,完全去除泥土和岩石,没有什么明显的变化。

标签: android opengl-es-2.0 glsles


【解决方案1】:

我会在分析器上运行您的代码(检查 Mali-400),但从外观上看,您正在杀死纹理缓存。对于计算的第一个像素,所有这 4 个纹理查找都被提取,但连续数据也被提取到纹理缓存中。对于下一个像素,您不是在访问缓存中的数据,而是看得很远(10、20..等),这完全违背了这种缓存的目的。

这当然是猜测,没有适当的分析很难判断。

编辑:@harism 也为您指出了这个方向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多