【问题标题】:Prevent loop unrolling in shader program when using ANGLE使用 ANGLE 时防止在着色器程序中展开循环
【发布时间】:2019-01-16 22:22:07
【问题描述】:

在我的 WEBGL 着色器中,我正在使用长度未知的循环(编译时)。

    do {
        sample = texture(uTex, posXY).a;
        accumulated += aSample * uAMultiplier;
    } while (accumulated < 0.8);

这在 OpenGL 浏览器上按预期工作,但默认情况下 windows chrome/ff 使用角度,展开循环,在这种情况下这是不可能的,导致编译错误。

错误:编译生成时出错
错误:无法链接程序
信息日志:
C:\fakepath(110,28-106): 错误 X4014: 不能在具有发散流控制的循环内进行梯度操作

C:\fakepath(59,12-96): 警告 X3570: 梯度指令在循环中使用不同迭代,强制循环展开
C:\fakepath(118,1-82): 错误 X3511: 无法展开循环,循环似乎没有及时终止(1024 次迭代)

是否有防止展开或以其他方式绕过必须循环的解决方案?

【问题讨论】:

    标签: glsl directx hlsl angle webgl2


    【解决方案1】:

    您可以尝试声明一个带有退出的静态循环。例如

    float accumulated = 0.0;
    #define ITERATION_LIMIT 100;
    for (int i = 0; i < ITERATION_LIMIT; ++i) {
      sample = texture(uTex, posXY).a;
      accumulated += aSample * uAMultiplier;
      if (accumulated >= 0.8) {
        break;
      }
    }
    

    当然最好选择一个合理的数字作为限制

    【讨论】:

    • 我试过#pragma optionNV (unroll 1) 似乎不起作用。我可以去调试 HLSL,它可以从上下文中获得,但是我发现了更多的错误,这些错误是由应用程序其他部分的角度引起的。所以我放弃了角度。您知道是否可以强制 OpenGL 而无需用户将浏览器重新启动到 opengl 模式?这种狗屁设计。我的 chrome 在 opengl 模式下运行更糟,但是要运行 webgl,没有错误,我不能依赖角度
    • #pragma 不是 WebGL 的一部分。强制 OpenGL 不会解决您的问题。问题不在于 ANGLE。问题是 WebGL 不允许您尝试做的事情。
    • 添加了一个可能的解决方案。见底部答案
    • pragma 是 webgl 或 GLSL 的一部分,可用于使用 optionNV 调整 HLSL - 我认为它可能仅适用于 nvidia,但它仍然不适用于我。您发布的是 OpenGL 2.0 规范,我使用 3.0 没有问题,并且支持没有确定限制的 do-while 循环。 WebGL 显然允许它并且它停止在角度平移。即使我将其调整为编译,它也会使我的 GPU 驱动程序崩溃!!我感谢您发布的解决方案,但由于多种特定原因,它不适用于我的情况。修复的唯一方法是使用 OpenGL over Angle
    • 您使用的是 WebGL 还是 WebGL2?您将问题标记为 WebGL 而不是 WebGL2。至于设备特定的编译指示,WebGL1 和 WebGL2 都不允许它们。 ANGLE 用于所有版本的 WebGL,无论 DirectX 是底层还是 OpenGL。它用作验证,以确保您没有尝试使用不属于 WebGL 的 GL 功能,并确保您的着色器在限制方面没有超出 WebGL 规范
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-11-30
    • 2017-05-22
    • 1970-01-01
    • 1970-01-01
    • 2012-11-22
    • 2016-10-27
    • 2017-01-29
    相关资源
    最近更新 更多