OpenGL ES 3.0编程指南:第五章. OpenGL ES Shading Language --- (三)

[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 矩阵在内存中以列优先顺序布局

你可能感兴趣的:(OpenGL ES 3.0编程指南:第五章. OpenGL ES Shading Language --- (三))