OpenGL ES 3.0编程指南:第五章. OpenGL ES
2016-09-29 本文已影响241人
别卡机
[TOC]
摘要
Shaders是OpenGL的基础,本章目的是确保你理解shader语言的下列概念:
- Variables and variable types
- Vector and matrix construction and selection
- Constants
- Structures and arrays
- Operators, control flow, and functions
- Input/output variables, uniforms, uniform blocks, and layout qualifiers
- Preprocessor and directive
- Uniform and interpolator packing
- Precision qualifiers and invariance
1. OpenGL ES Shading Language Basics
本章主要来介绍一个shader到底是由哪些组成的。你可能已经发现,shader语法和C语言很像,如果你理解C语言,你也会很容易理解shader语法。当然,shader语言和C语言还是有一些地方是不太一样的。
2. Shader Version Specification
Shader文件的第一行一般都是版本声明,编译器会根据所声明的版本来检查shader语法是否正确
#version 300 es
如果shader文件没有声明版本,则会认为它使用的是OpenGL ES 2.0的shader版本1.0。为了使版本号相匹配,OpenGL ES 3.0的shader版本直接从1.0跳到了3.0 。
3.Variables and Variable Types
在计算机绘图中,有两个基础类型:向量和矩阵,这两种类型对于OpenGL也是十分重要的。下表列出了shader语言中的数据类型:
分类 | 类型 |
---|---|
标量 | float, int, uint, bool |
浮点向量 | float, vec2, vec3, vec4 |
整数向量 | int, ivec2, ivec3, ivec4 |
无符号整数向量 | uint, uvec2, uvec3, uvec4 |
布尔向量 | bool, bvec2, bvec3, bvec4 |
矩阵 | mat2(or mat2x2), mat2x3, mat2x4, mat3x2, mat3(mat3x3), mat3x4, mat4x2, mat4x3, mat4(mat4x4) |
变量声明时必须指定类型,可以在声明时初始化,也可以先声明后初始化。
4.Variable Constructors
Shader语言在类型转换方面有严格的规则,变量只能跟同类型的变量进行操作运算或赋值,不允许隐式类型转换。Shader语言中有很多构造器可以用来进行类型转换,每一个内建变量类型都有一组相关的构造器。下面看几个示例:
float myFloat = 1.0;
float myFloat = 1; <wrong>
bool myBool = true;
int myInt = 0;
int myInt2 = 0.0; <wrong>
myFloat = float(myBool); // Convert from bool -> float
myFloat = float(myInt); // Convert from int -> float
myBool = bool(myInt); // Convert from int -> bool
同样,构造器也可以用来转化或初始化向量数据类型。向量构造器的参数传递有两种方法:
- 如果只有一个标量参数,则改制用来设置向量的所有值
- 如果提供了多个标量或者向量参数,则向量的值从左到右按照这些参数值来设置。如果提供了多个标量参数,那么参数的数量至少应该和向量的分量一样多。
vec4 myVec4 = vec4(1.0); // myVec4 = {1.0, 1.0, 1.0, 1.0}
vec3 myVec3 = vec3(1.0, 0.0, 0.5); // myVec3 = {1.0, 0.0, 0.5}
vec3 temp = vec3(myVec3); // temp = myVec3
vec2 myVec2 = vec2(myVec3); // myVec2 = {myVec3.x, myVec3.y}
myVec4 = vec4(myVec2, temp); // myVec4 = {myVec2.x, myVec2.y, temp.x, temp.y}
矩阵的构造很灵活,有一些基本规则:
- 如果只提供了一个标量参数,则该值被放在矩阵的对角线上。
- 矩阵可以由多个向量参数构成。比如,一个mat2可以由两个vec2构成
- 矩阵可以由多个标量参数构成。每个参数代表一个值。
矩阵的构造实际可以比上面说的更灵活,只要分量足够,矩阵可以由任意标量和向量组合构成。
OpenGL ES中的矩阵都是以列优先储存,当构造矩阵时,参数会按照列顺序进行填充。
mat 3 myMat3 = mat3(1.0, 0.0, 0.0, // first column
0.0, 1.0, 0.0, // second column
0.0, 0.0, 1.0); // third column