我请求有关this question中的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...
}
我知道这看起来很奇怪,但这确实是解释问题/错误行为所需的全部代码。
我的问题是:当我为u_light_active传入某个大于0的值时,为什么不执行循环?当我硬编码一些整数,例如4,而不是使用统一的u_light_active时,它工作得很好。
还有一件事,这只出现在Android上,而不是桌面上。我使用LibGDX在两个平台上运行相同的代码。
如果需要更多信息,您可以查看original question,但我不想复制和粘贴这里的所有内容。我希望这种保持简短的方法能得到赞赏,否则我会把所有的东西都复制过来。
3条答案
按热度按时间yeotifhr1#
基本上,GLSL指定实现可以将循环限制为具有“恒定”边界。这是为了使优化代码以并行运行变得更简单(不同像素的不同循环计数会很复杂)。我相信在某些实现中,常量甚至必须很小。请注意,规范只指定了“最小”行为,因此一些设备可能支持比规范所要求的更复杂的循环控制。
下面是对约束的一个很好的总结:http://www.khronos.org/webgl/public-mailing-list/archives/1012/msg00063.html
下面是GLSL规范(参见附录A的第4节):http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf
cpjpxq1n2#
http://www.opengl.org/discussion_boards/showthread.php/171437-can-for-loops-terminate-with-a-uniform
http://www.opengl.org/discussion_boards/showthread.php/177051-GLSL-loop-problem-on-Radeon-HD-cards
http://www.opengl.org/discussion_boards/showthread.php/162722-Problem-when-using-uniform-variable-as-a-loop-count-in-fragment-shader
https://www.opengl.org/discussion_boards/showthread.php/162535-variable-controlled-for-loops
如果你有一个静态循环,它可以被展开并变成静态常量查找。如果您绝对需要使其动态化,则需要将索引数据存储到1D纹理中并对其进行采样。
我猜,台式机上的硬件比平板电脑上的更先进。希望这个能帮上忙!
atmip9wb3#
这是一个有趣的半个答案,或者说,是我所选择的根本问题的解决方案。
使用‘id’调用的以下函数传递为着色器脚本块的ID,并使用[[ThingToReplace,ReplaceWith],]字符串格式的两个组件数组的数组填充‘swaps’。在创建着色器之前调用。
在该脚本中:
在C语言中,这是一种非常类似宏的方法,因为它模拟了一个预处理器。
在GLSL中:
或者;