shader在GPU的多核中并行执行,vertex shader每个图元顶点执行一次,fragment shader每个图元像素执行一次
Shader的语法
OpenGL Shading Language是C的子集,稍有扩展
Storage Qualifier
attribute
: vertex shader的输入,gles =(per-vertex data)=> vertex shadervarying
: vertex shader的输出、被插值后变成fragment shader的输入,vertex shader =(per-vrtex data)=…=(interpolated data)=> fragment shader
Only those varying variables statically used (i.e. read) in the fragment shader must be declared in the vertex shader; declaring superfluous varying variables in the vertex shader is permissible.uniform
: vertex shader和fragment shader的输入,global shared readonly dataconst
: local variables & function parameters can only use const storage qualifier<none, default>
: function return types & structure fields do not use storage qualifiers
Parameter Qualifier
<none, default>
/in
、out
、inout
Precision Qualifier
-
highp
: ~float32、mediump
: ~float16、lowp
: ~int10 -
precision precision-qualifier type;
// 指定某类型的默认precisionfragment shader中没有自动声明默认precision,vertex shader中自动声明了默认precision
Build-in Varible
特定于vertex shader的输出变量:
high vec4 gl_Position; // should be written to
medium float gl_PointSize; // may be written to
特定于fragment shader的变量:
medium vec4 gl_FragColor; // 用gl_FragColor,gl_FragData[0]因兼容性原因还存在
mediup vec4 gl_FragCoord; // 由vertex shader插值生成的(x,y,z,1/w),readonly
bool gl_FrontFacing; // 某surface是否是正面,readonly
medium vec2 gl_PointCoord; // 只当本fragment位于某点(a point primitive)内时有效,
// (x,y)表示本fragment在该点内的相对位置,x,y在[0,1]间,readonly
Build-in Function
三角函数、指数对数、常用函数
dot
: vector dot product,cross
: vector dot product*
: vector component-wise multiply || matrix linear algebraic matrix multiplymatrixCompMult
: matrix component-wise multiplication
Misc
mat2
、mat3
、mat4
: column major matrix,先列后行
Shader的用法
- 编译glProgram:将vertex shader和fragment shader编译、链接得到glProgram
- 传入数据:获得shader中变量的location,向这个location传入数据
- 画图:glDrawArrays或glDrawElements
2.1 传入uniform数据
glGetUniformLocation
拿到locationglUniform
/glUniformMatrix
向location传入数据
2.2 传入attribute数据
glGetAttribLocation
拿到location,或者在glProgram链接之前已经glBindAttribLocation
设置过location,然后glEnableVertexAttribArray
激活这个locationglVertexAttribPointer
向location传入数据在某结构中的偏移
若传入的数据量较大,可使用FBO(Frame Buffer Object)。这样就把数据拷到GPU,每次draw时从GPU取数据,避免每次draw时从CPU=>GPU的数据拷贝。
- 使用FBO+
glDrawArrays
时第2步要改成:- 准备数据:用
glBufferData
给GL_ARRAY_BUFFER填上数据,GL_ARRAY_BUFFER已用glBindBuffer
绑定到某个buffer(GLuint) glVertexAttribPointer
向location数据在GL_ARRAY_BUFFER中的偏移,GL_ARRAY_BUFFER已用glBindBuffer
绑定到数据buffer
- 准备数据:用
若用glDrawElements
画图,还需传入顶点索引,要将上述GL_ARRAY_BUFFER换成GL_ELEMENT_ARRAY_BUFFER
2.3 传texture时需要传texture data和texture coord
- 传texture data这一
uniform
(sample2D类型):glGetUniformLocation
拿到location- 准备数据:用
glTexImage2D
给GL_TEXTURE_2D填上数据。GL_TEXTURE_2D已glActiveTexture
激活某个索引值(默认是0,GL_TEXTURE0),并glBindTexture
绑定某个buffer(GLuint)到该索引值,且设置好texture params。 glUniform
向location传入GL_TEXTURE_2D某个buffer的索引值(默认传0)。GL_TEXTURE_2D需glActiveTexture
激活该索引值(默认是0,GL_TEXTURE0),并glBindTexture
绑定某个buffer(GLuint)到该索引值。
- 传texture coord这一attribute:同attribute用法
References
- Khronos的《OpenGL ES Shading Language》