20170320–uniform-(2)
1、 普通uniform在主程序变得复杂的时候会难以维护与使用,所以引入uniform block。Uniform块可以在不同程序之间共享。
2、 Uniform块必须存储在buffer中,你可以通过更改绑定的buffer或直接修改buffer中的内容来设置uniform块。即使在更改主程序后,uniform块还可以继续保持与buffer的绑定关系。这种uniform的使用方式即为UBO(Uniform Buffer Object)。实际上,普通uniform其实就是使用的默认的uniform块。
3、 Uniform的使用案例:
Uniform uniformBlock
{
float scale;
vector3 translation;
float rotation[3];
mat4 projection_matrix;
} transform;
上面即定义了一个uniform块并同时声明了一个uniformBlock的实例transform。在shader中,你可以通过transform.scale这种方式来使用这些uniform变量。如果想声明多个实例,并且这些实例拥有各自的缓冲区,你可以把transform设置成数组。数组中每个实例使用同样的location
4、 GLSL 的uniform块的布局分为两种,一种是标准布局,一种是默认布局。
5、 标准布局(STD140)的内存对齐规则:基本原则就是偏移量一定是应该对齐的量的整数倍,比如标量的对齐长度是4,那么他们的偏移量必须是4的倍数;2元素的数组或vec2的对齐长度是8,那么偏移量应该是8的倍数,3\4元素数组或者vec3\vec4的对齐长度是16,那么他们的偏移量应该是16的倍数。矩阵看作是向量的数组,矩阵的偏移量就是该类型向量的对齐长度的整数倍。
标准布局的样例代码:
layout(std140)uniform myUniformBlock
{
float scale;
vector3 translation;
float rotation[3];
mat4 projection_matrix;
} transforms;
6、标准布局的uniform块的成员的偏移量可以自行指定,比如:
layout(std140) uniform myUniformBlock
{
layout(offset=32) vec4 foo;//布局合理,因为32是16的倍数(vec4要求对齐字节数为16)
layout(offset=8) vec2 bar;//布局合理,因为8是8的倍数(vec2要求对齐字节数为8)
layout(offset=48) vec3 baz;//布局合理,因为48是16的倍数(vec3/vec4要求对齐字节数为16)
} transform;