Glsl 使用“角度”时防止着色器程序中的循环展开

Glsl 使用“角度”时防止着色器程序中的循环展开,glsl,directx,hlsl,angle,webgl2,Glsl,Directx,Hlsl,Angle,Webgl2,在我的WEBGL着色器中,我在编译时使用长度未知的循环 do { sample = texture(uTex, posXY).a; accumulated += aSample * uAMultiplier; } while (accumulated < 0.8); 这在OpenGL浏览器上可以正常工作,但默认情况下,windows chrome/ff使用角度展开循环,这在本例中是不可能的,会导致编译错误 错误:编译生成时出错 错误:无法链

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

    do {
        sample = texture(uTex, posXY).a;
        accumulated += aSample * uAMultiplier;
    } while (accumulated < 0.8);
这在OpenGL浏览器上可以正常工作,但默认情况下,windows chrome/ff使用角度展开循环,这在本例中是不可能的,会导致编译错误

错误:编译生成时出错 错误:无法链接程序 信息日志: C:\fakepath110,28-106:错误X4014:在具有发散流控制的回路内不能有渐变操作

C:\fakepath59,12-96:警告X3570:在循环中使用渐变指令,迭代次数不断变化,迫使循环展开 C:\fakepath118,1-82:错误X3511:无法展开循环,循环似乎没有及时终止1024次迭代


是否有一种解决方案可以防止展开或绕过循环?

您可以尝试声明一个带有出口的静态循环。比如说

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选项nv unroll 1似乎不起作用。我可以去调试HLSL,这是可以从上下文中获得的,但我发现了更多的错误,这些错误是由应用程序的其他部分中的角度引起的。所以我放弃了角度。您知道用户不必重新启动浏览器就可以强制OpenGl进入OpenGl模式吗?这真是个狗屎设计。我的chrome在opengl模式下运行得更差,但要运行webgl,没有错误,我不能依赖anglepragma不是webgl的一部分。强制使用OpenGL不会解决您的问题。问题不在于角度。问题是WebGL不允许您尝试执行的操作。添加了一个可能的解决方案。请参阅底部的答案Pragma是webgl或GLSL的一部分,可用于使用optionNV调整HLSL-我认为它可能仅适用于nvidia,但它仍然不适用于我。您发布的是OpenGL 2.0规范,我使用的是3.0,没有问题,并且支持do-while循环,没有确定的限制。WebGL显然允许它,并且它在角度平移时停止。即使我将其调整为编译,它也会使我的GPU驱动程序崩溃!!我很感激您发布的解决方案,但由于多个具体原因,它在我的情况下不起作用。唯一的解决方法是使用OpenGl而不是Angle。您使用的是WebGL还是WebGL2?您将问题标记为WebGL而不是WebGL2。对于特定于设备的杂注,WebGL1和WebGL2都不允许它们。在所有版本的WebGL中都使用角度,无论DirectX是在引擎盖下还是在OpenGL中。它用作验证,以确保您不会尝试使用不属于WebGL的GL功能,并确保着色器在限制方面不会超出WebGL规范