要计算多个光源,像C ++ std::vector
这样在GLSL中具有可调整大小的数组将非常方便。数组的大小必须始终能够变化,而无需重新编译着色器。
有一些命令,库等可以做到吗?
要计算多个光源,像C ++ std::vector
这样在GLSL中具有可调整大小的数组将非常方便。数组的大小必须始终能够变化,而无需重新编译着色器。
有一些命令,库等可以做到吗?
vector
并不是魔术。它通过分配内存来工作。 GLSL中没有内存分配。着色器使用它有权访问的资源。不允许着色器仅创建资源。
解决此问题的典型方法是创建一个统一数组,该数组中具有最大数量的灯光,然后您提供一个单独的制服,告诉着色器该数组中有多少灯光中包含真实数据。本质上,您要预先分配一个固定大小的缓冲区,该固定大小表示您可以使用的最大灯光数量。
通常没关系。如果您的灯光多于固定大小限制,那么您需要为其余的灯光添加更多的灯光通道(如果您有很多灯光,则应该或应该使用延迟渲染)。
通常,此类固定大小的数组是UBO的一部分,因此您可以轻松地对其进行更新并换出。与常规的GLSL制服相比,UBO的限制也更大。
如果您出于某些原因绝对需要任意限制,则可以使用包含照明数据的SSBO。 SSBO可以静态调整大小:
layout(binding = #,std430) buffer light_data
{
Light lights[];
};
lights
中的条目数将由Light
的大小以及与SSBO缓冲区绑定索引#
关联的缓冲区范围中的字节数确定。因此,如果Light
的大小为32个字节,并且您应用了8192个字节的缓冲区范围,那么lights.length()
将返回256个条目。
话虽这么说,您应该真正尝试在UBO限制内生活。 UBO访问可能比SSBO更快,因为它们(在某些硬件中)在执行着色器之前直接加载到着色器内存中。相比之下,SSBO始终是全局内存访问。