【问题标题】:Pass array of floats to fragment shader via texture通过纹理将浮点数组传递给片段着色器
【发布时间】:2018-08-29 04:40:52
【问题描述】:

我正在尝试通过纹理将一组浮点数(在我的情况下为音频波)传递给片段着色器。它可以工作,但我得到了一些缺陷,好像从 1px 高度纹理读取的值不可靠。

这种情况发生在条形宽度和数量的许多组合中。

我从纹理中获取值:

precision mediump float;
...
uniform sampler2D uDisp;
...
void main(){
  ...
  float columnWidth = availableWidth / barsCount;
  float barIndex = floor((coord.x-paddingH)/columnWidth);
  float textureX = min( 1.0, (barIndex+1.0)/barsCount );
  float barValue = texture2D(uDisp, vec2(textureX, 0.0)).r;
  ...

如果我使用其他东西而不是纹理中的值,则问题似乎不存在。

barValue = barIndex*0.1;

知道可能是什么问题吗?为此目的使用纹理是一个坏主意吗? 我使用Pixi.JS 作为 WebGL 框架,所以我无法访问低级 API。

使用渐变纹理的数据和许多条形,问题变得非常明显。

更新:看起来问题与 textureX 值的一致性有关。 尝试不同的公式,如barIndex/(barsCount-1.0) 可以减少噪音。将其包裹在 min 上肯定会增加噪音。

【问题讨论】:

  • 如果使用:float textureX = min( 1.0, (barIndex+0.5)/barsCount ) 会更好吗? (那是 +0.5 而不是 +1.0)?这意味着您从纹素的中心而不是边缘进行采样。此外,您应该使用精确的 highp 浮点数;而不是 mediump。
  • @Columbo 不幸的是,这些更改都没有任何区别。
  • 另外,请确保不要为纹理生成/使用 mipmap。

标签: glsl webgl pixi.js


【解决方案1】:

通常mediump 不足以用于任何非平凡纹理的纹理坐标,因此请尽可能使用highp。这在某些较旧的 GPU 上并不总是可用,因此取决于平台,这可能无法解决您的问题。

如果您知道自己在进行 1:1 映射,那么也可以使用 GL_NEAREST 而不是 GL_LINEAR,因为量化效果更有可能隐藏一些精度副作用。

鉴于您可能知道列数和条数,您可能可以以 fp32 精度预先计算 CPU 上的一些值(例如,预先计算 1/columns 并将其作为统一值传递)。传入 0 到 1 之间的小值总是比传入大值然后除以更好地保持浮点精度。

【讨论】:

  • 我一定会尝试预先计算一些变量,谢谢!不确定在 Pixi 中是否可以将 GL_LINEAR 更改为 GL_NEAREST。
  • 我不能同意你的第一段,通常mediump 足以从纹理中采样,还要注意精度限定符对桌面平台没有影响(因为它没有在问题中明确提及) 我认为 OP 正在遇到这个问题。
  • FP16 为接近 1.0 的值提供 11 位小数尾数精度,这意味着 0 到 1 之间的mediump ST 纹理坐标有足够的位来处理 2048 纹素宽的纹理(它值接近零时效果更好,但这是接近 1) 的极限。对于像样的GL_LINEAR 过滤,您通常希望保留至少 16 个子纹理寻址步骤,以便将 2048 减少到 256。如果您的输入 UV 坐标使用任何类型的环绕模式,情况会变得更糟。
  • 顶点缓冲区中的输入数据可以是mediump,但您真的很想在着色器中使用highp 来进行不同的插值和纹理坐标上的任何计算。
【解决方案2】:

原来问题不在于从纹理中读取值,而在于绘图。我没有使用 IF,而是切换到 step,问题就消失了。

vec2 topLeft = vec2(
  paddingH + (barIndex*columnWidth) + ((columnWidth-barWidthInPixels)*0.5),
  top
);
vec2 bottomRight = vec2(
  topLeft.x + barWidthInPixels,
  bottom
);
vec2 tl = step(topLeft, coord);
vec2 br = 1.0-step(bottomRight, coord);
float blend = tl.x * tl.y * br.x * br.y;

我猜想通过 IF 比较浮点数在着色器中不是很可靠。

【讨论】:

  • 这正是需要 MVCE 的原因
  • @LJᛃ MVCE 存在?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-27
  • 2019-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多