得鹿梦鱼 得鹿梦鱼

webGL着色器和GLSL

顶点着色器

一个顶点着色器的工作是生成裁剪空间坐标值

void main{    gl_Position = doMathToMakeClipspaceCoordinates}

每个顶点调用一次顶点着色器,每次调用都需要设置一个特殊的全局变量gl_Position,该变量的值就是裁剪空间坐标值

顶点着色器需要的数据,可以通过一下三种方式获得

  1. Attributes属性(从缓冲中获取的数据)
  2. Uniforms全局变量(在一次绘制中对所有的顶点保持一致值)
  3. 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, offset

Uniforms全局变量

全局变量在一次绘制过程中传递给着色器的值都一样,

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中获取颜色信息。片段着色器所需的数据,可以通过以下三种方式获取

  1. Uniforms全局变量
  2. Textures纹理
  3. 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是一个强类型的语言