Проблемы с HALF_FLOAT на графических процессорах в Мали - PullRequest
0 голосов
/ 10 марта 2019

У меня есть отчеты от моих пользователей о проблемах с рендерингом данных наполовину на некоторых устройствах с графическими процессорами Mali (Huawei Honor 9 и Samsung Galaxy S10 + с Mali G71 и G76 соответственно).

Это приводит кискаженный рендеринг на этих устройствах при правильной работе на графических процессорах Adreno и PowerVR.

Я дважды проверил код, и он кажется правильным:

...
     if (model.hasHalfFloats()) {
         GLES20.glVertexAttribPointer(shaderOutline.getRm_Vertex(), 3, GLES20.GL_FLOAT, false, 18, 0);
         GLES20.glVertexAttribPointer(shaderOutline.getRm_Normal(), 3, getGL_HALF_FLOAT(), false, 18, 12);
     } else {
         GLES20.glVertexAttribPointer(shaderOutline.getRm_Vertex(), 3, GLES20.GL_FLOAT, false, 24, 0);
         GLES20.glVertexAttribPointer(shaderOutline.getRm_Normal(), 3, GLES20.GL_FLOAT, false, 24, 12);
     }
...

/**
 * Returns either OES extension for GL 16-bit floats (if used in ES 2.0) or ES 3.0 constant.
 */
protected int getGL_HALF_FLOAT() {
    if(isES3()) {
        return GLES30.GL_HALF_FLOAT;
    } else {
        return GL_HALF_FLOAT_OES;
    }
}

Код, похоже, правильно обнаруживает OpenGL ES 3и используйте GLES30.GL_HALF_FLOAT значение в getGL_HALF_FLOAT().

Пример кода шейдера:

    vertexShaderCode = "attribute vec4 rm_Vertex;\r\n" + 
            "attribute mediump vec3 rm_Normal;\r\n" +
            "uniform mat4 view_proj_matrix;\r\n" + 
            "uniform float uThickness1;\r\n" + 
            "void main( void )\r\n" + 
            "{\r\n" + 
            "   vec4 pos = vec4(rm_Vertex.xyz, 1.0);\r\n" + 
            "   float dist = (view_proj_matrix * pos).w;\r\n" + 
            "   vec4 normal = vec4(rm_Normal, 0.0);\r\n" + 
            "   pos += normal * uThickness1 * dist;\r\n" + 
            "   gl_Position = view_proj_matrix * pos;\r\n" + 
            "}";

    fragmentShaderCode = "precision mediump float;\r\n" + 
            "uniform vec4 uColor;\r\n" + 
            "void main( void )\r\n" + 
            "{\r\n" + 
            "    gl_FragColor = uColor;\r\n" + 
            "}";

1 Ответ

1 голос
/ 10 марта 2019

Я думаю, у вас есть проблемы с выравниванием. Из этого фрагмента (и вашего вершинного шейдера):

GLES20.glVertexAttribPointer(shaderOutline.getRm_Normal(), 3, getGL_HALF_FLOAT(), false, 18, 12);

Я могу сделать вывод, что вы пытаетесь создать структуру вершины следующим образом:

float fPos[3];
half fNormal[3];

Вы получили шаг вершины из 18, который предположительно был получен путем сложения отдельных размеров элементов (3*sizeof(float))+(3*sizeof(half)) = 12 + 6 = 18.

Однако, шаг должен быть 20, потому что в противном случае ваши вершины будут смещены. 4-байтовые числа должны начинаться с 4-байтовой границы, но это не так.

Из спецификации GLES3:

Клиенты должны согласовывать элементы данных в соответствии с требованиями клиентской платформы, с дополнительным требованием базового уровня, чтобы смещение в пределах буфера к элементу данных, содержащему N базовых машинных единиц, было кратным N

...