我正在开发一个3d引擎,它应该适用于移动平台。目前,我只想做一个原型,将工作在iOS和使用正演渲染。在发动机中,场景可以有不同类型的不同数量的灯(定向、点等)。在呈现时,为每个对象(网格)构造一个影响该对象的光数组。数组将始终有一个或多个元素。我可以将光源信息打包到一维纹理中,并传递给着色器。灯的数量可以放在这个纹理中,也可以作为一个单独的制服传递(我还没有试过,但这是我在谷歌搜索后的想法)。
问题是,并非所有glsl实现都支持具有可变限制的for循环。因此,我不能写一个着色器,它将循环通过光源,并期待它工作在一个广泛的平台上。如果不支持具有可变限制的for 循环,那么是否有任何技术可以支持着色器中的可变灯数?
的想法:实现了对着色器源的一些预处理,以手动展开循环,以适应不同的灯数。所以在这种情况下,如果我用一种类型的着色器渲染所有的物体,如果灯的数量限制在1到3之间,我最终会有3个不同的着色器(自动生成),用于1,2和3盏灯。是个好主意吗?
发布于 2014-06-16 03:55:28
由于着色器的源代码由您在运行时传入的字符串组成,因此没有什么可以阻止您动态构建源代码,这取决于灯光的数量,或者控制您需要什么样的着色器的任何其他参数。
如果您使用的是着色器代码位于单独文本文件中的设置,并且希望保持这种设置,则可以利用以下事实:您可以在着色器代码中使用预处理器指令。假设您使用LIGHT_COUNT来表示您的着色代码中的灯数。然后,在编译着色器代码时,要为所需的计数提供定义,例如:
#define LIGHT_COUNT 4由于glShaderSource()接受一个字符串数组,您甚至不需要任何字符串操作来将其连接到从文件读取的着色器代码。您只需将其作为附加字符串传入glShaderSource()。
着色编译是相当昂贵的,所以你可能会想要缓存着色程序的每一个轻计数。
另一个选择是Andon在评论中提出的建议。您可以为您需要的光计数的上限编写着色器,然后传递作为每个光源的乘数的制服。对于你不需要的灯,你把乘法器设置为0。这并不是很有效率,因为你正在为你不需要的光源做额外的计算,但是它很简单,如果它符合你的性能要求的话,可能会很好。
https://stackoverflow.com/questions/24221005
复制相似问题