Shading
- Vertex Processor
- Fragment Processor
- 变量和类型
- 基础类型
- 数据结构
- 数组
- 限定词
- 存储限定词
- 精度限定词
- 精度的含义
- 不同精度的范围
- 默认精度
- 运算符和表达式
- 运算法
- 强转
- Vector和Matrix构造
- Vector构造
- Matrix构造
- Vector Components
- Vector and Matrix运算
- 内置函数
- 角度和三角函数
- 指数函数
- 通用函数
- 几何函数
- 矩阵函数
- 数组关系函数
- 纹理查找函数
参考如下
GLSL_ES_Specification_1.00
GLSLangSpec.1.20
opengl-es-sdk-for-android
Shading
如果我们打算做渲染的话,现代OpenGL需要我们至少设置一个顶点和一个片段着色器。
Vertex Processor
顶点着色器主要的目的是把3D坐标转为另一种3D坐标(后面会解释),同时顶点着色器允许我们对顶点属性进行一些基本处理。
Fragment Processor
片段着色器的主要目的是计算一个像素的最终颜色,这也是所有OpenGL高级效果产生的地方。通常,片段着色器包含3D场景的数据(比如光照、阴影、光的颜色等等),这些数据可以被用来计算最终像素的颜色。
变量和类型
基础类型
Type | Meaning |
void | for functions that do not return a value or for an empty parameter list |
bool | a conditional type, taking on values of true or false |
int | a signed integer |
float | a single floating-point scalar |
vec2 | a two component floating-point vector |
vec3 | a three component floating-point vector |
vec4 | a four component floating-point vector |
bvec2 | a two component Boolean vector |
bvec3 | a three component Boolean vector |
bvec4 | a four component Boolean vector |
ivec2 | a two component integer vector |
ivec3 | a three component integer vector |
ivec4 | a four component integer vector |
mat2 | a 2×2 floating-point matrix |
mat3 | a 3×3 floating-point matrix |
mat4 | a 4×4 floating-point matrix |
sampler2D | a handle for accessing a 2D texture |
samplerCube | a handle for accessing a cube mapped texture |
数据结构
和C是一样的使用方式,例如:
struct light {
float intensity;
vec3 position;
} lightVar;
light lightVar2;
数组
和C是一样的使用方式,例如:
float frequencies[3];
uniform vec4 lightPosition[4];
const int numLights = 2;
light lights[numLights];
限定词
存储限定词
Qualifier | Meaning |
< none: default > | local read/write memory, or an input parameter to a function |
const | a compile-time constant, or a function parameter that is read-only |
attribute | linkage between a vertex shader and OpenGL ES for per-vertex data |
uniform | value does not change across the primitive being processed, uniforms form the linkage between a shader, OpenGL ES, and the application |
varying | linkage between a vertex shader and a fragment shader for interpolated data |
- 局部变量只能使用const存储限定词
- 函数参数只能使用const存储限定词
- 函数返回值和结构体字段不能使用任何存储限定词
精度限定词
精度的含义
Qualifier | Meaning |
highp | Satisfies the minimum requirements for the vertex language described above. Optional in the fragment language. |
mediump | Satisfies the minimum requirements above for the fragment language. Its range and precision has to be greater than or the same as provided by lowp and less than or the same as provided by highp. |
lowp | Range and precision that can be less than mediump, but still intended to represent all color values for any color channel. |
不同精度的范围
默认精度
设置默认精度precision precision-qualifier type;,Fragment需要通过判断宏GL_FRAGMENT_PRECISION_HIGH的值来确定是否支持highp精度。
顶点语言具有以下预先声明的全局范围的默认精度语句:
precision highp float;
precision highp int;
precision lowp sampler2D;
precision lowp samplerCube;
片段语言具有以下预先声明的全局范围的默认精度语句:
precision mediump int;
precision lowp sampler2D;
precision lowp samplerCube;
运算符和表达式
运算法
GLES SL有以下运算符,下面列出了他们的优先级(Precedence)以及组合律(Associativity)。
强转
int(bool) // converts a Boolean value to an int
int(float) // converts a float value to an int
float(bool) // converts a Boolean value to a float
float(int) // converts an integer value to a float
bool(float) // converts a float value to a Boolean
bool(int) // converts an integer value to a Boolean
- 当使用构造函数将浮点数转换为int时,会删除浮点值的小数部分
- 当使用构造函数将int或float转换为bool时,0和0.0转换为false,非零值转换为true
- 当使用构造函数将布尔值转换为int或float时,false为转换为0或0.0,并且true转换为1或1.0
- 身份构造函数,例如float(float)也是合法的,但使用很少
- 具有非标量参数的标量构造函数可用于从非标量中获取第一个元素,例如,构造函数float(vec3)将选择vec3参数的第一个组件。
Vector和Matrix构造
Vector构造
vec3(float) // initializes each component of with the float
vec4(ivec4) // makes a vec4 with component-wise conversion
vec2(float, float) // initializes a vec2 with 2 floats
ivec3(int, int, int) // initializes an ivec3 with 3 ints
bvec4(int, int, float, float) // uses 4 Boolean conversions
vec2(vec3) // drops the third component of a vec3
vec3(vec4) // drops the fourth component of a vec4
vec3(vec2, float) // vec3.x = vec2.x, vec3.y = vec2.y, vec3.z = float
vec3(float, vec2) // vec3.x = float, vec3.y = vec2.x, vec3.z = vec2.y
vec4(vec3, float)
vec4(float, vec3)
vec4(vec2, vec2)
Matrix构造
// To initialize the diagonal of a matrix with all other elements set to zero:
mat2(float)
mat3(float)
mat4(float)
// To initialize a matrix by specifying vectors, or by all 4, 9, or 16 floats for mat2, mat3 and mat4 respectively. The floats are assigned to elements in column major order.
mat2(vec2, vec2);
mat3(vec3, vec3, vec3);
mat4(vec4, vec4, vec4, vec4);
mat2(float, float,
float, float);
mat3(float, float, float,
float, float, float,
float, float, float);
mat4(float, float, float, float,
float, float, float, float,
float, float, float, float,
float, float, float, float);
Vector Components
component names | Note |
{x, y, z, w} | Useful when accessing vectors that represent points or normals |
{r, g, b, a} | Useful when accessing vectors that represent colors |
{s, t, p, q} | Useful when accessing vectors that represent texture coordinates |
Vector and Matrix运算
除少数例外,操作是基于组件的。 当运算符对向量或矩阵进行运算时,它会按分量方式对向量或矩阵的每个分量进行独立运算。 例如:
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;
相当于:
u.x = dot(v, m[0]); // m[0] is the left column of m
u.y = dot(v, m[1]); // dot(a,b) is the inner (dot) product of a and b
u.z = dot(v, m[2]);
还有
u = m * v;
相当于:
u.x = m[0].x * v.x + m[1].x * v.y + m[2].x * v.z;
u.y = m[0].y * v.x + m[1].y * v.y + m[2].y * v.z;
u.z = m[0].z * v.x + m[1].z * v.y + m[2].z * v.z;
还有
mat m, n, r;
r = m * n;
相当于:
r[0].x = m[0].x * n[0].x + m[1].x * n[0].y + m[2].x * n[0].z;
r[1].x = m[0].x * n[1].x + m[1].x * n[1].y + m[2].x * n[1].z;
r[2].x = m[0].x * n[2].x + m[1].x * n[2].y + m[2].x * n[2].z;
r[0].y = m[0].y * n[0].x + m[1].y * n[0].y + m[2].y * n[0].z;
r[1].y = m[0].y * n[1].x + m[1].y * n[1].y + m[2].y * n[1].z;
r[2].y = m[0].y * n[2].x + m[1].y * n[2].y + m[2].y * n[2].z;
r[0].z = m[0].z * n[0].x + m[1].z * n[0].y + m[2].z * n[0].z;
r[1].z = m[0].z * n[1].x + m[1].z * n[1].y + m[2].z * n[1].z;
r[2].z = m[0].z * n[2].x + m[1].z * n[2].y + m[2].z * n[2].z;
内置函数
角度和三角函数
假定指定为角度的功能参数以弧度为单位。这些函数在任何情况下都不会导致被零除的误差。如果比率的除数为0,则结果将不确定。
这些都以组件方式运行,该说明是针对每个组件的。
指数函数
这些都以组件方式运行,该说明是针对每个组件的。
通用函数
这些都以组件方式运行,该说明是针对每个组件的。
几何函数
这些在矢量上作为矢量操作,而不是按分量操作。
矩阵函数
数组关系函数
定义(或保留)关系和相等运算符(<,<=,>,>=,==,!=)以生成标量布尔结果。对于矢量结果,请使用以下内置函数。在下面,bvec是bvec2、bvec3或bvec4之一的占位符,ivec是ivec2、ivec3或ivec4之一的占位符,vec是vec2、vec3或vec4的占位符。在所有情况下,任何特定调用的输入和返回向量的大小必须匹配。
纹理查找函数