0
\$\begingroup\$

I have this project, that has a default shader, that just draws models and textures. Recently I decided to add a second shader that does a fancy effect, and is used only on some of the objects drawn.

After compiling the project for Linux or Windows, it all works as expected. When compiling the project to Android, only on specific devices, the new shader doesn't work, while on other devices I tried, it all works.

My shaders

Below is my default vertex shader specifically made for Android devices, this one works on all devices and draws everything without any editing or effect. As far as I understand, the fragment shaders work, so I'll omit them.

    #version 310 es

    in vec4 position;
    in vec3 colour;
    in vec2 texCoord;

    uniform mat4 matrix;
    uniform mat4 matrixProjection;

    out vec2 outTexCoord;
    out vec4 outColour;

    void main() {
            gl_Position = matrixProjection *matrix *position;
            outTexCoord  = texCoord;
            outColour  = vec4(colour.rgb, 1);
    }

I hope this looks fairly straight-forward. matrixProjection is the projection matrix, and matrix is the model-view matrix. They both work as expected and I'm able to render a whole scene without issue.

Now here is a simplified version of my new shader:

    #version 310 es

    in vec4 position;
    in vec3 colour;
    in vec2 texCoord;

    uniform mat4 matrix;
    uniform mat4 matrixProjection;
    uniform float animationCurrent;

    out vec2 outTexCoord;
    out vec4 outColour;

    void main() {
            gl_Position = matrixProjection *matrix *position;

            if (animationCurrent > 0.0) {
                    gl_Position.y += 5.0;
            }

            outColour = vec4(colour.rgb, 1.0);
            outTexCoord  = texCoord;
    }

The only difference of the new shader is the new uniform animationCurrent, and an extra if statement that will modify the gl_Position.y of some vertices. Any object that is using this shader, is not drawn at all on the screen on some devices.

What I've tried

From the new shader, if I remove the entire if statement, it all works and it displays objects as-is. If I replace the if statement with if (true) it still works, but it just displays all vertices of objects drawn with it slightly higher. If I replace it with if (false) it still works as expected.

So for some reason, just referencing animationCurrent causes the object to not be drawn.

I also tried replacing the if statement with if (matrix[0][0] > 0.0) and it still draws the object, it looks like there's something specifically wrong with animationCurrent. I tried adding another matrix uniform variable, and set its value the same way as I do matrix, but it wouldn't draw the object either.

This should mean that the value of animationCurrent is not relevant, and the fact that it's a uniform float doesn't matter either.

Hardware

The problem occurs on an android phone with this hardware:

Device: Moto E (4) Plus - 7.1.1
Vendor graphic card: ARM
Renderer: Mali-T720
Version OpenGL: OpenGL ES 3.1 v1.r12p1-01alp0.62f282720426ab7712f1c6b996a6dc82
Version GLSL: OpenGL ES GLSL ES 3.10

And this android tablet with similar hardware:

Device: Kindle Fire 8
Vendor graphic card: ARM
Renderer: Mali-T720
Version GL: OpenGL ES 3.1 v1.r26p0-01rel0.526d936ea9da20486773a9aaceecd920
Version GLSL: OpenGL ES GLSL ES 3.10

This is an android tablet where everything works as expected:

Device: Lenovo TB-X505F - 10
Vendor graphic card: Qualcomm
Renderer: Adreno (TM) 504
Version GL: OpenGL ES 3.2 V@415.0 (GIT@f345350, I0760943699, 1580221225) (Date:01/28/20)
Version GLSL: OpenGL ES GLSL ES 3.20

And here is a slightly older device that works. I've modified the shader a bit to support an older glsl version, but the idea is the same:

Device: Kindle Fire 7
Vendor graphic card: ARM
Renderer: Mali-450 MP
Version GL: OpenGL ES 2.0
Version GLSL: OpenGL ES GLSL ES 1.00

Question

My primary goal, is to understand what is causing this. Have I missed something very obvious? Is this a very edge-case bug related to the hardware?

I'm still learning how to support different devices with different versions of glsl, so it's very likely I've missed something.

Any information you have, let me know. I'm willing to try a few things on different devices to find more about this issue.

\$\endgroup\$
0
0
\$\begingroup\$

I've just found what the problem is, and the workaround for it.

On those specific devices, it seems that declaring the uniforms in a specific order matters. I'm not sure if that's a bug with Mali-T720 (since both devices use it) or with GLSL 3.10, as I don't have enough devices to test this.

My solution was changing from this:

uniform mat4 matrix;
uniform mat4 matrixProjection;
uniform float animationCurrent;

To this:

uniform float animationCurrent;
uniform mat4 matrix;
uniform mat4 matrixProjection;

The shader compiles successfully and renders all the special effects modified by animationCurrent. I don't know what's the order of all different uniform types, but hopefully this can help someone having a similar issue in the future.

If anybody knows why this happens, and if it's indeed a bug with the hardware, or something mentioned by a specific version of OpenGL, let me know, as I'd still like to know why this behaves this way.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.