Android 对于着色器代码中的循环,使用硬编码数字,但不使用统一变量

Android 对于着色器代码中的循环,使用硬编码数字,但不使用统一变量,android,opengl-es-2.0,glsl,libgdx,vertex-shader,Android,Opengl Es 2.0,Glsl,Libgdx,Vertex Shader,我请求帮助解决中的OpenGL ES 2.0问题。 我觉得答案很奇怪。 因此,我决定问这个问题,希望能够理解发生了什么 下面是一段错误的顶点着色器代码: // a bunch of uniforms and stuff... uniform int u_lights_active; void main() { // some code... for ( int i = 0; i < u_lights_active; ++i ) { // do s

我请求帮助解决中的OpenGL ES 2.0问题。 我觉得答案很奇怪。 因此,我决定问这个问题,希望能够理解发生了什么

下面是一段错误的顶点着色器代码:

// a bunch of uniforms and stuff...
uniform int u_lights_active;

void main()
{
    // some code...

    for ( int i = 0; i < u_lights_active; ++i )
    {
        // do some stuff using u_lights_active
    }

    // some other code...
}
//一堆制服之类的东西。。。
统一的国际照明系统;
void main()
{
//一些代码。。。
用于(int i=0;i
我知道这看起来很奇怪,但这确实是解释问题/错误行为所需的全部代码

我的问题是:为什么当我为u\u lights\u active传入大于0的值时,循环没有执行? 当我硬编码一些整数时,例如4,而不是使用统一的u_lights_active,它工作得很好

还有一件事,这只会出现在Android上,而不会出现在桌面上。我使用LibGDX在两个平台上运行相同的代码

如果需要更多的信息,你可以看看,但我不想复制和粘贴所有的东西在这里。 我希望这种保持简短的方法得到赞赏,否则我会把所有的东西都复制过来

我期待一个解释:)

谢谢

如果您有一个静态循环,它可以展开并形成静态常量查找。如果您确实需要使其动态化,则需要将索引数据存储到1D纹理中,并对其进行采样


我猜桌面上的硬件比平板电脑上的更先进。希望这有帮助

基本上,GLSL指定实现可以限制循环,使其具有“常量”边界。这使得优化并行运行的代码变得更简单(不同像素的不同循环计数会很复杂)。我相信在某些实现中,常数甚至必须很小。请注意,规范只指定了“最小”行为,因此某些设备可能支持比规范要求更复杂的循环控件

下面是约束的一个很好的总结:

以下是GLSL规范(参见附录A第4节):
这是一个有趣的半答案,或者说是我所选择的根本问题的解决方案

调用以下函数时,将“id”作为着色器脚本块的id传递,并使用[[ThingToReplace,ReplaceWith],]字符串格式的2个组件数组数组填充“swaps”。在创建着色器之前调用

在javascript中:

var ReplaceWith = 6;

function replaceinID(id,swaps){
    var thingy = document.getElementById(id);
    for(var i=0;i<swaps.length;i++){
        thingy.innerHTML = thingy.innerHTML.replace(swaps[i][0], swaps[i][1]);
    }
}

replaceinID("My_Shader",[['ThingToReplace',ReplaceWith],]);
var ReplaceWith=6;
函数替换id(id,交换){
var thingy=document.getElementById(id);
对于(var i=0;i
for(int i=0;i<ThingToReplace;i++){
    ;//whatever goes here
}
const int val = ThingToReplace;

for(int i=0;i<val;i++){
    ;//whatever goes here
}