【问题标题】:Boolean logic on my fragments takes a lot of VRAM, how can I avoid this?我的片段上的布尔逻辑需要大量 VRAM,我该如何避免这种情况?
【发布时间】:2019-02-28 06:35:35
【问题描述】:

我有一个来自 GLSL 330 的非常简单的请求:

if (colorOut.r <= 1.0 && colorOut.r > 0.7)
{
    colorOut.r=*color_1.r;
}

我有超过 40 次这样的比较。

但是,这给我带来了麻烦,因为有人告诉我 AND、NOT 等语句会占用大量视频内存,我正在为 After Effects 开发一个插件,而那些碰巧使用它们没有强大的 GPU(在大多数情况下——我做过一项调查,其中大多数使用移动版本的中端 GPU)。所以我想我会问你们是否有可能替代使用 AND 或者即使,因为我被告知片段着色器根本不喜欢 if 在主分支中。

谢谢。

【问题讨论】:

  • 您说“AND、NOT 等语句占用大量视频内存”。这是不正确的,简单的布尔运算不需要任何大量内存(如果您有很多内存,它们可能需要大量的计算时间,但 VRAM 不需要)。执行路径的分歧(例如 if 语句)可能会导致显着减速,因为将采用的路径不可预测,因此无法有效利用缓存等。请参阅this question(其中大部分也适用于 GPU)。

标签: opengl glsl fragment-shader


【解决方案1】:

像您这样的多路复用场景,您可以使用无分支编程。例如,您可以使用类似的东西。布尔运算符是“近似的”。

colorOut.r = mix(colorOut.r, (colorOut.r*color_1.r), 
    ( clamp(pow(1-colorOut.r, 20), 0, 1)
    * clamp(pow(colorOut.r-0.7, 20), 0, 1) ) );

请注意,三元组通常不会引起太多问题,这在资源上应该很容易,因为它不会导致分支:

colorOut.r = mix(colorOut.r, (colorOut.r*color_1.r), 
    ( colorOut.r <= 1 && colorOut.r > 0.7 ? 1 : 0 );

【讨论】:

  • 那么三元可以吗?很高兴听到。谢谢。
  • @MajorDespard:重要的是,您的程序不会“偏离太多”。两个不同计算之间的多路复用通常不会发散,因为任何一个计算都可以轻松放入寄存器中。如果您进行不同的函数调用、从不同的纹理位置获取等等,这将是一个完全不同的故事。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-10
  • 1970-01-01
  • 1970-01-01
  • 2011-11-23
  • 1970-01-01
相关资源
最近更新 更多