在glsl v100中将大数组从顶点传递到片段着色器

时间:2015-12-07 20:35:51

标签: opengl-es-2.0 glsles

(OpenGL ES 2.0)(glsl v100)

我正在尝试将大型内核传递给片段着色器以进行卷积操作。我开始通过动态创建着色器并硬编码所有内核颜色,但出于某种原因,如果我通过索引31读取数组,则着色器不会编译并且不会给出错误。下面是我试图找出问题所在的一些代码。

顶点着色器

navigator.appVersion.indexOf('Edge') > -1

片段着色器

attribute vec4 position;
attribute vec4 inputTextureCoordinate;
varying float kernelColors[33];

void main()
{
    gl_Position = position;

    kernelColors[0] = 0.000000;
    kernelColors[1] = 1.000000;
    kernelColors[2] = 1.000000;
    kernelColors[3] = 1.000000;
    kernelColors[4] = 1.000000;
    kernelColors[5] = 1.000000;
    kernelColors[6] = 1.000000;
    kernelColors[7] = 1.000000;
    kernelColors[8] = 1.000000;
    kernelColors[9] = 1.000000;
    kernelColors[10] = 1.000000;
    kernelColors[11] = 1.000000;
    kernelColors[12] = 1.000000;
    kernelColors[13] = 1.000000;
    kernelColors[14] = 1.000000;
    kernelColors[15] = 1.000000;
    kernelColors[16] = 1.000000;
    kernelColors[17] = 1.000000;
    kernelColors[18] = 1.000000;
    kernelColors[19] = 1.000000;
    kernelColors[20] = 1.000000;
    kernelColors[21] = 1.000000;
    kernelColors[22] = 1.000000;
    kernelColors[23] = 1.000000;
    kernelColors[24] = 1.000000;
    kernelColors[25] = 1.000000;
    kernelColors[26] = 1.000000;
    kernelColors[27] = 1.000000;
    kernelColors[28] = 1.000000;
    kernelColors[29] = 1.000000;
    kernelColors[30] = 1.000000;
    kernelColors[31] = 1.000000;
    kernelColors[32] = 1.000000;
}

可能有更好的方法来做到这一点,但我仍然想知道为什么上面的代码无法编译。

关于其他方法 - glsl 100中没有'flat'限定符,所以如果它甚至可以改变/优化任何东西,我就不能应用它。另外,如果我将内核数据作为纹理加载,如果我不能拥有动态索引,我如何迭代像素?

我需要将每个像素与内核进行卷积,内核不会在帧与帧之间发生变化,但在某些情况下我可能需要将其换成另一个内核。

1 个答案:

答案 0 :(得分:1)

根据您运行的设备,可以使用的变化量有限制(搜索MAX_VARYING_VECTORS和OpenGLES),如果超过它,则着色器将无法编译。

但是使用变换来存储每个像素相同的内核是完全浪费资源。请记住,为顶点着色器中的顶点设置了变化,然后GPU为每个像素插入它们之间,所以在这里你告诉GPU插入所有片段相同的值,这是一个完全无用的操作。

更好的解决方案:

  • 在片段着色器中使用制服来存储内核(就像您也可以从应用代码中更改它一样......)
  • 将内核存储在您在片段着色器中采样的纹理中,在这种情况下,请确保纹理使用最近的过滤(同样,您可以根据应用代码更改纹理。只要您需要...)