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: ~int10precision 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》