OpenGL ES 2.0如何访问LUT

时间:2016-03-08 18:18:35

标签: android opengl-es opengl-es-2.0

我已经为片段着色器创建了一个查找表,并且我将它作为一个统一的浮点数组传递。

A.b

我的程序在大多数设备上运行正常,但我遇到了一个设备,我收到了这个错误:

#extension GL_OES_EGL_image_external : require
precision mediump float;
uniform samplerExternalOES sTexture;
uniform float hueLut[360];

我听说过这可以使用Error: uniform variables in fragment shader do not fit in 224 vectors. 完成,但我不知道如何在android中完成此操作。在片段着色器中访问我的lut以避免这些类型的错误的最佳方法是什么?另外,正如你可能会说的那样,我对opengl很新,所以任何示例代码都会有很大的帮助。感谢。

1 个答案:

答案 0 :(得分:0)

不再将纹理视为图像,只需将其视为2d随机访问数组。确定适合该实现认为可接受的360值的最小大小。 32x16很可能是无害的。

将360值表格填充并存储为512字节 - 255 10 0,因为正常的纹理值缩放规则将适用 - 并提交作为GL_LUMINANCE纹理,请求最近的采样。

将纹理单元粘合并提供给合适的采样器均匀,然后如(硬编码为32x16,即席编写,因此请检查逻辑):

lowp vec2 samplingLocation = vec2(
    (mod(index, 16.0) + 0.5) / 32.0,
    (index + 16.0) / (32.0 * 16.0)
);
lowp float oneOrZero = texture2d(tableUniform, samplingLocation);

逻辑是:

  • x坐标是环绕的 - 坐标表中的后一个值可能具有较低的x位置,即较早的值 - 因此需要仅使用索引的低部分,这是通过mod实现的GLSL ES 2.0,因为没有按位操作;
  • y坐标是单调增加的值 - 后来的值总是至少与之前的值一样高 - 但我们不需要明确地屏蔽x,因为我们正在使用最近的位置采样,所以在正确的方框内的任何东西都可以;
  • 我在x指数中添加了0.5,然后将其除以纹理的宽度以瞄准纹素的中心,降低了采样错误的风险;
  • 由于同样的原因,我在分割之前已经将16.0添加到y索引中,除了真正讨价还价的是row = index / 32.0; y = (row + 0.5) / 16.0;所以0.5由于其他因素而增加了32.0在错误的地方。

如果您有GL分析器,您可能会对依赖纹理提取进行负面评论,即在运行片段着色器之前无法预测的那些。正常的问题是提前缓存纹理的正确部分。使用32x16纹理,您可能不会那么担心。