webGL着色器和GLSL
顶点着色器
一个顶点着色器的工作是生成裁剪空间坐标值
void main{ gl_Position = doMathToMakeClipspaceCoordinates}每个顶点调用一次顶点着色器,每次调用都需要设置一个特殊的全局变量gl_Position,该变量的值就是裁剪空间坐标值
顶点着色器需要的数据,可以通过一下三种方式获得
- Attributes属性(从缓冲中获取的数据)
- Uniforms全局变量(在一次绘制中对所有的顶点保持一致值)
- Textures纹理(从像素或纹理元素中获取的数据)
Attributes属性
var buffer = gl.createBuffer;gl.bindBuffergl.ARRAY_BUFFER, buffer;gl.bufferDatagl.ARRAY_BUFFER, somedata, gl.STATIC_DRAWvar position = gl.getAttribLocationsomeShaderProgram, "a_position"gl.enableVertexAttribArraypositiongl.vertexAttribPointerposition, numComponents, type, false, stride, offsetUniforms全局变量
全局变量在一次绘制过程中传递给着色器的值都一样,
attribute vec4 a_position;uniform vec4 u_offset;void main{ gl_Position = a_position + u_offset;}var offsetLoc = gl.getUniformLocationsomeProgram, "u_offset";gl.uniform4fvoffsetLoc, [1, 0, 0, 0]; // 向右偏移一半屏幕宽度片段着色器
一个片段着色器的工作是为当前光栅化的像素提供颜色值,通常是以下的形式
precision mediump float;void main{ gl_FragColor = doMathToMakeAColor}每个像素都将调用一次片段着色器,每次调用需要从你设置的特殊全局变量gl_FragColor中获取颜色信息。片段着色器所需的数据,可以通过以下三种方式获取
- Uniforms全局变量
- Textures纹理
- Varyings可变量
Uniforms 全局变量
全局变量在一次绘制过程中传递给着色器的值都一样,
Textures纹理
在着色器中获取纹理信息,可以先创建一个sampler2D类型全局变量,然后用GLSL方法texture2D 从纹理中提取信息
precision mediump float; uniform sampler2D u_texture; void main { vec2 texcoord = vec20.5, 0.5; // 获取纹理中心的值 gl_FragColor = texture2Du_texture, texcoord;}var tex = gl.createTexture;gl.bindTexturegl.TEXTURE_2D, tex;var level = 0;var width = 2;var height = 1;var data = new Uint8Array[ 255, 0, 0, 255, // 一个红色的像素 0, 255, 0, 255, // 一个绿色的像素];gl.texImage2Dgl.TEXTURE_2D, level, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data;gl.texParameterigl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR;var someSamplerLoc = gl.getUniformLocationsomeProgram, "u_texture";var unit = 5; // 挑选一个纹理单元gl.activeTexturegl.TEXTURE0 + unit;gl.bindTexturegl.TEXTURE_2D, tex;gl.uniform1isomeSamplerLoc, unit;Varyings 可变量
可变量是一种顶点着色器给片段着色器传值的方式
为了使用可变量,要在两个着色器中定义同名的可变量。 给顶点着色器中可变量设置的值,会作为参考值进行内插,在绘制像素时传给片段着色器的可变量
attribute vec4 a_position; uniform vec4 u_offset; varying vec4 v_positionWithOffset; void main { gl_Position = a_position + u_offset; v_positionWithOffset = a_position + u_offset;}precision mediump float; varying vec4 v_positionWithOffset; void main { // 从裁剪空间 -1 <-> +1 转换到颜色空间 0 -> 1. vec4 color = v_positionWithOffset * 0.5 + 0.5; gl_FragColor = color;}GLSL
GLSL全称是 Graphics Library Shader Language (图形库着色器语言),是着色器使用的语言。 它有一些不同于JavaScript的特性,主要目的是为栅格化图形提供常用的计算功能。 所以它内建的数据类型例如vec2, vec3和 vec4分别代表两个值,三个值和四个值, 类似的还有mat2, mat3 和 mat4 分别代表 2x2, 3x3 和 4x4 矩阵。
值得注意的是GLSL是一个强类型的语言