LibGDX着色器无处不在,但我的Android设备

时间:2016-07-26 07:19:28

标签: android opengl-es libgdx glsl

作为我上一个问题(GLSL : Accessing an array in a for-loop hinders performance)的延续,我遇到了一个全新且恼人的问题。

所以,我有一个执行黑洞效果的着色器。

着色器在我的计算机,Android模拟器和ShaderToy上完美运行 - 但由于某些原因,即使代码完全相同,也无法在我的Android设备上运行。

当我放大太远时会出现问题。无论出于何种原因,当我的缩放到达某一点时 - 整个背景放大然后缩小并变得疯狂。像这样:

What is happening

什么时候看起来像这样:

What should happen

但是,如果我更改它,它在我的设备上可以正常工作:

#ifdef GL_ES
precision mediump float;
#endif

到此:

#ifdef GL_ES
precision highp float;
#endif

这个问题是它也会将我的FPS从60降低到~40。

我认为问题在于我的Android设备的OpenGL版本是Gdx.gl.glGetString(GL20.GL_VERSION)的“OpenGL ES 3.0”。

但我无法弄清楚如何将我的版本设置为OpenGL 2.0,因为AndroidApplicationConfiguration类给了我很少甚至没有选项。

我尝试将<uses-feature android:glEsVersion="0x00020000" android:required="true" />放入清单中,但它仍会打印“OpenGL ES 3.0”。

我仍然不知道这是否真的是问题的原因,所以这就是我在这里问的原因。感谢您抽出宝贵时间阅读/回答我的问题:)。

P.S。这是Shader代码:

#ifdef GL_ES
precision mediump float;
#endif

const int MAX_HOLES = 4;

uniform sampler2D u_sampler2D;

varying vec2 vTexCoord0;

struct BlackHole {
    vec2 position;
    float radius;
    float deformRadius;
};

uniform vec2 screenSize;
uniform vec2 cameraPos;
uniform float cameraZoom;

uniform BlackHole blackHole[MAX_HOLES];

void main() {
    vec2 pos = vTexCoord0;

    float black = 0.0;
    for (int i = 0; i < MAX_HOLES; i++) {
        BlackHole hole = blackHole[i];
        vec2 position = (hole.position - cameraPos.xy) / cameraZoom + screenSize*0.5;
        float radius = hole.radius / cameraZoom;
        float deformRadius = hole.deformRadius / cameraZoom;

        vec2 deltaPos = vec2(position.x - gl_FragCoord.x, position.y - gl_FragCoord.y);
        float dist = length(deltaPos);
        float distToEdge = max(deformRadius - dist, 0.0);

        float dltR = max(sign(radius - dist), 0.0);
        black = min(black+dltR, 1.0);

        pos += (distToEdge * normalize(deltaPos) / screenSize);
    }

    gl_FragColor = (1.0 - black) * texture2D(u_sampler2D, pos) + black * vec4(0, 0, 0, 1);
}

1 个答案:

答案 0 :(得分:3)

正如您所发现的那样,问题在于fp16(mediump)缺乏精确性,这是通过使用fp32(highp)来解决的。对于fp16和fp32,大多数数学单位的吞吐量都会翻倍,这也解释了性能的下降。

查询驱动程序GLES版本将返回最大支持版本,而不是当前EGL上下文的版本,因此您所看到的是预期的。

另请注意&#34; highp&#34;在OpenGL ES 2.0片段着色器中是可选的,因此无法保证着色器可以在OpenGL ES 2.0上下文中的某些GPU上运行。例如,Mali-4xx系列仅支持fp16片段着色器(我认为还有一些基于过去经验的OpenGL ES 2.0 Vivante GPU)。

在OpenGL ES 3.0中,highp在片段着色器中是必需的,因此可以保证在那里工作。