[TOC]
10. Functions
函数的使用方法和C语言中的类似。如果一个方法想要在它被定义前使用,那么必须先声明这个方法。OpenGL ES和C语言中函数的不同之处在于参数的限制符,OpenGL ES提供了一些特殊的限制符来指明参数的作用:
修饰符 | 说明 |
---|---|
in | 默认值。指明参数通过值传递,并且不可被修改 |
inout | 指明参数通过引用传递,可以被修改 |
out | 指明参数的值不被传入函数,但在函数返回时可以被修改 |
要注意的一点是:OpenGL ES中的函数不能递归。原因是一些OpenGL的实现的函数调用是将程序代码内嵌到最终程序中的。
11. Built-In Functions
Shader语言的一大好处就是它有很多内置函数,例如dot、pow。要想写好shader,熟练掌握这些内置函数是很有必要的,书中的附录B详细介绍了各种内置函数。
12. Control Flow Statements
Shader语言的控制流语句和C语言中的类似。除了基本的if-else-then语句,也有for、while、do-while语句,在OpenGL ES 2.0中,循环语句的使用有着严格的限制规则,而在3.0版本中这些限制已经不在了。在3.0中,循环语句得到了完全的支持,但这并不是说循环语句在性能上没有什么影响。
13. Uniforms
Uniform是shader语言中的一个变量修饰符,用来存储只读值,由应用程序通过API传递给shader。
Uniform变量储存在硬件里的“常量储存区”中,由于硬件的常量储存区的大小通常是固定的,所以uniform的个数也是有限制的,这些限制值可以通过gl_MaxVertexUniformVectors和gl_MaxFragmentUniformVectors这两个内置变量来获得,(或者通过glGetintegerv调用GL_MAX_VERTEX_UNIFORM_VECTORS和GL_MAX_FRAGMENT_UNIFORM_VECTORS来获得)。OpenGL ES 3.0的各个实现至少应提供256个vertex uniform vector和224个fragment uniform vector。
14. Uniform Blocks
Uniform缓冲对象在某些情况下比单独的uniform变量更有优势:
- 通过使用uniform缓冲对象,uniform数据只需设置一次就可以在多个program对象间共享
- uniform缓冲对象可以储存更多数量的uniform数据
- 在uniform缓冲对象之间切换比一次加载一个uniform更高效
在uniform block中的uniform可以直接被访问,就像一个常规形式的uniform:
#version 300 es
uniform TransformBlock
{
mat4 matViewProj;
mat3 matNormal;
mat3 matTexGen;
};
layout(location = 0) in vec4 a_position;
void main()
{
gl_position = matViewProj * a_position;
}
许多可选的layout限定符可以用来指明uniform缓冲对象在内存中的布局方式。Layout限定符既可以限定单独的uniform block,也可以用做限定全局所有的uniform blocks,设置全局layout的方式如下:
layout(shared, column_major) uniform; //默认值
layout(packed, row_major) uniform;
单独的uniform block可以重载全局的layout,而且一个uniform block里的一个单独的uniform也可以设置layout:
layout(std140) uniform TransformBlock
{
mat4 matViewProj;
layout(row_major) mat4 matNormal;
mat3 matTexGen;
};
下表列出了所有的layout限定符:
限定符 | 说明 |
---|---|
shared | shared限定符指明在不同的shader或不同的程序中,uniform block的内存布局是相同的。当使用shared限定符时,row_major/column_major限定符也必须相同。会覆盖packed和std140。(默认值) |
packed | packed限定符指明编译器可以优化uniform block的内存布局。当使用packed限定符时,必须查询偏移位置,而且无法再shader之间或program之间共享。会覆盖std140和shared。 |
std140 | std140限定符指明uniform block的内存布局基于OpenGL ES的标准规范的。会覆盖shared和packed。 |
row_major | 矩阵在内存中以行优先顺序布局 |
column_major | 矩阵在内存中以列优先顺序布局 |
网友评论