【问题标题】:OpenGL ES 2.0 how to access LUTOpenGL ES 2.0 如何访问 LUT
【发布时间】:2021-09-11 00:54:30
【问题描述】:

我为我的片段着色器创建了一个查找表,并将它作为一个统一的浮点数组传入:

#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.

我听说这可以使用texture2D 来完成,但我不知道如何在 android 中完成。在片段着色器中访问我的 LUT 以避免此类错误的最佳方法是什么?

【问题讨论】:

  • 你的 GL 实现是否支持GL_OES_texture_float
  • @genpfault 我将我正在使用的扩展名添加到问题中。这也是我应该添加的吗?
  • hueLut 的实际内容是什么?值的范围是多少?它们是否再现了连续图?
  • @Tommy 这基本上是一个布尔映射,0 表示假,1 表示真。

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


【解决方案1】:

不要将纹理视为图像,而是将其视为 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 in GLSL ES 2.0,因为没有按位运算;
  • y 坐标是单调增加的——后面的值总是有一个至少和前面的值一样高的 y 位置——但我们不需要明确屏蔽 x,因为我们使用的是最近的位置采样,所以正确框内的任何东西都可以;
  • 在将 x 索引除以纹理宽度之前,我已将 0.5 添加到纹理像素的中心,从而降低了采样错误的风险;
  • 出于同样的原因,我在 y 索引中添加了 16.0,然后将其除以 row = index / 32.0; y = (row + 0.5) / 16.0;,因此 0.5 乘以 32.0,否则会出现错误的位置。李>

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-14
    • 1970-01-01
    相关资源
    最近更新 更多