官方文档
https://www.khronos.org/files/opengles_shading_language.pdf
CSDN上也有一些翻译之后的文档.
着色语言非常类似于C和matlab语言, 所以跟C语言相同的部分, 就不写了, 它由两部分组成, 顶点处理器和片段处理器.
顶点处理器决定着色的几何位置, 片段处理器决定着色的颜色.
类型 | 含义 |
---|---|
vec2/vec3/vec4 | 分别为2/3/4维的浮点数向量 |
bvec2/bvec3/bvec4 | 分别为2/3/4维的Bool值向量 |
mat2/mat3/mat4 | 分别为2x2, 3x3, 4x4的矩阵 |
sampler2D | 二维纹理的句柄 |
samplerCube | 我也没用过, 不知道怎么用 |
坐标系(x, y, z, w), 前三维很容易理解, 第4维w可以理解为远近. w=0时, 表示物体无限远. 越远的物体, 看起来越小, 越近的物体, 看起来越大
修饰符 | 含义 |
---|---|
const | 变量不允许被修改 |
attribute | 只能用于顶点着色器, 将GL API中的数据与shader中的变量进行关联 |
uniform | 声明一个全局的只读变量, 可以使用API进行初始化 |
sampler2D | 二维纹理的句柄 |
varying | 关联顶点着色器与纹理着色器中的变量, 比如顶点着色器将值写入varying 变量, 纹理着色器可以通过这个变量读取值 |
修饰符 | 含义 |
---|---|
in | |
out | 出参 |
inout | 同时是入参和出参 |
对于integer和float, 可以通过精度修饰符设置它的取值范围.
(对于C语言开发者来说, 32位平台上, float和int都占用固定的4个字节)
gl es用修饰符规定的相应的最小取值范围和最低精度, (也就是说平台提供的精度实际上更高)
修饰符 | float取值范围 | float精度 | integer取值范围 |
---|---|---|---|
highp | (-262, 262) | 2-16, 即精确到二进制的小数点后16位 | (-216, -216) |
mediump | (-214, 214) | 2-10, 即精确到二进制的小数点后10位 | (-210, 210) |
lowp | (-2, 2) | 2-8, 即精确到二进制的小数点后8位 | (-2-8, 28) |
使用方法
定义一个高精度的浮点数
highp float h2 = 2.3;
//将int的精度调整为高精度
precision highp int;
vec2 a = ... ; 使用某个计算方法给a赋值
...
col = texture2D(tex, a); //优化器可能会重新计算a的值, 导致a的值出现变化
为了禁止优化器重新计算, 可以使用不变量修饰符
invariant vec2 a = ... ; 使用某个计算方法给a赋值
...
col = texture2D(tex, a); //优化器可能会重新计算a的值, 导致a的值出现变化
struct light {
float intensity;
vec3 position;
};
light lightVar = light(3.0, vec3(1.0, 2.0, 3.0));
两个结构体变量可以使用==
, !=
进行比较, 每个成员都相等时, 这两个变量才相等
构造过程
vec4 color = vec4(0.0, 1.0, 0.0, 1.0);
vec4 rgba = vec4(1.0); // sets each component to 1.0
mat3 mat = mat3( 1, 1, 1,
0, -0.39465, 2.03211,
1.13983, -0.58060, 0);
向量
每个元素都有3个名称, 方便进行取值操作.
第1个元素, x, r, s
第2个元素, y, g, t
第3个元素, z, b, p
第4个元素, w, a, q
3个名称是都是同一个元素, 可以通用. 但是为了代码的可读性, 表示颜色时用(r,g,b,a), 表示位置时用(x, y, z, w)
表示纹理时用(s, t, p, q)
vec4 v4 = vec4(1.0, 2.0, 3.0, 4.0);
//取值操作
float x = v4.x;
float y = v4.y;
float r = v4.r;
float g = v4.g;
vec2 xy = v4.xy;
vec2 rg = v4.rg;
//赋值操作
v4.x= 7.0;
v4.xy = vec2(5.0, 6.0);
矩阵
mat4 m;
m[1] = vec4(2.0); // sets the second column to all 2.0
m[0][0] = 1.0; // sets the upper left element to 1.0
m[2][3] = 2.0; // sets the 4th element of the third column to 2.0
vec3 v, u;
float f;
v = u + f;
等同于
v.x = u.x + f;
v.y = u.y + f;
v.z = u.z + f;
vec3 v, u, w;
w = v + u;
等同于
w.x = v.x + u.x;
w.y = v.y + u.y;
w.z = v.z + u.z;
不懂的, 看线性代数
向量与矩阵相乘, 结果仍为向量
vec3 v, u;
mat3 m;
u = v * m;
矩阵与向量相叉乘, 结果仍为矩阵
vec3 v, u;
mat3 m;
u = v * m;
需要使用内置函数dot
vec3 v, u, w
w = dot(v,u);
以gl_
开头的变量属于内置变量, 开发者自己的变量不能以gl_
开头.
变量名 | 类型 | 着色器 | 含义 |
---|---|---|---|
gl_Position | vec4 | 顶点着色器 | 存放顶点坐标值, 必须赋值 |
gl_PointSize | float | 顶点着色器 | 决定点的光栅大小, 不是必需的 |
gl_FragColor | vec4 | 纹理着色器 | 设置着色的颜色 |
gl_FragData | 纹理着色器 | 不知道干什么用的 | |
gl_FragCoord | vec4 | 纹理着色器 | 只读变量, 当前着色点的4维坐标 |
gl_PointCoord | vec2 | 纹理着色器 | 只读变量, 当前着色点的2维坐标 |
三角函数, 数学函数, 几何函数, 矩阵函数, 向量函数, 这些函数直接查询文档好了. 这里不多说了
vec4 texture2D (sampler2D sampler, vec2 coord )
通过坐标查找着色采样.
其它的函数, 我也不太理解.
官方文档很长很长, 关键点差不多就是上面的这些内容