无法在三星设备上分配变量 [OpenGL ES]

Failed to allocate varyings on Samsung devices [OpenGL ES]

在三星设备上编译模糊着色器失败并出现错误:分配变量失败

着色器代码如下:

#ifdef GL_ES
precision mediump float;
#endif

varying vec2 v_texCoord;
varying vec2 v_blurTexCoords[14];
varying vec2 pixel_size;

uniform vec2 v_resolution;
uniform sampler2D u_texture;
uniform mat4 u_projTrans;

void main()
{
     ...
}

在其他设备上运行良好,三星设备可能有什么问题?

看起来您只是超出了您的实施所支持的变量数量。最大可变向量数可以用:

查询
GLint maxVarying == 0;
glGetIntegerv(GL_MAX_VARYING_VECTORS, &maxVarying);

合规实施的最低要求限制是 8。这意味着至少支持 8 个类型 vec4

您的案例很有趣,因为您总共使用了 16 种类型 vec2。您可能认为这将适合 space of 8 vec4 值,因此应该适用于所有设备。但它比这更复杂。

有关此主题的详细信息可以在 GLES 1.00 规范第 111 页开始的附录 A.7 中找到,标题为 "Counting of Varyings and Uniforms"。这是大约 2.5 页的非常技术性的描述,我无法在这里重复。但本质上,它描述了一种可能的打包算法,实现 可以 在兼容的情况下使用。他们可以使用包装更有效的东西,但他们不必这样做。

此打包算法中适用于您的案例的一个关键部分如下:

Vectors always occupy registers in a single row. Elements of an array must be in different rows. E.g. vec4 will always occupy one row; float[8] will occupy one column. Since it is not permitted to split a variable, large arrays e.g.. for varyings, float[16] will always fail with this algorithm.

这意味着对于仅支持 8 个不同向量并使用此兼容算法的实现,您可以 适合您的 14 vec2 值数组。它可以容纳 16 个 vec2 类型的单个值。或者例如一个包含 8 个 vec2 值和 8 个 vec2 类型的单个值的数组,如果我正确理解规范的话。但没有一个数组的大小大于 8。

为了让您的着色器安全编译,您需要一个 returns 至少 14 的实现 GL_MAX_VARYING_VECTORS 限制。

这个问题真的帮助了我。

我最终拆分了数组并且工作正常:

varying vec2 v_blurTexCoords0;
varying vec2 v_blurTexCoords1;
varying vec2 v_blurTexCoords2;
varying vec2 v_blurTexCoords3;
varying vec2 v_blurTexCoords4;
varying vec2 v_blurTexCoords5;
varying vec2 v_blurTexCoords6;
varying vec2 v_blurTexCoords7;
varying vec2 v_blurTexCoords8;
varying vec2 v_blurTexCoords9;
varying vec2 v_blurTexCoords10;
varying vec2 v_blurTexCoords11;
varying vec2 v_blurTexCoords12;
varying vec2 v_blurTexCoords13;