我从用户那里收到有关在某些使用Mali GPU(华为荣誉9和三星Galaxy S10 +分别带有Mali G71和G76)的设备上渲染半浮点数据的问题的报告。
这会导致这些设备呈现乱码,而在Adreno和PowerVR GPU上却可以正常工作。
我已经仔细检查过代码,这似乎是正确的:
...
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" +
"}";
答案 0 :(得分:1)
我认为您遇到对齐问题。从此代码段(和您的顶点着色器)开始:
tf.io.parse_single_sequence_example()
我可以推断出您正在尝试这样的顶点结构:
GLES20.glVertexAttribPointer(shaderOutline.getRm_Normal(), 3, getGL_HALF_FLOAT(), false, 18, 12);
您得出的顶点跨度为18,大概是通过将元素float fPos[3];
half fNormal[3];
的各个大小相加得出的。
但是,步幅应为20,因为否则您的顶点将未对齐。 4字节浮点数必须在4字节边界处开始,但事实并非如此。
根据GLES3规范:
客户必须使数据元素与客户平台的要求保持一致,并附加基本级别要求,即缓冲区中包含N个基本机器单元的数据的偏移量应为N的倍数。