WebGL笔记_着色器(三)

来源:互联网 发布:思迅软件费用 编辑:程序博客网 时间:2024/06/07 03:46

着色器

  • 顶点着色器(Vertex shader) : 用来描述顶点的特性 . 例如 : 顶点的位置,顶点的颜色.
  • 片元着色器(Fragment shader) : 进行逐片处理过程 , 例如光照 . 片元是图像的单元,可以理解为像素, 片元着色器又被叫做片段着色器,像素着色器.

代码执行顺序

浏览器加载页面—–>执行js代码—–>执行WebGL相关方法—–>执行顶点着色器代码(逐点操作)—–>执行片元着色器代码(逐片操作)—–>渲染到颜色缓冲区

举例

var VSHADER_SOURCE =   'attribute vec4 a_Position;\n' + // attribute variable  'void main() {\n' +  '  gl_Position = a_Position;\n' +  '  gl_PointSize = 10.0;\n' +  '}\n'; // Fragment shader programvar FSHADER_SOURCE =    'precision mediump float;\n' +    'uniform vec4 u_FragColor;\n' +    'void main(){\n' +    '   gl_FragColor = u_FragColor;\n' +    '}\n';function main() {      var canvas = document.getElementById('webgl');      var gl = getWebGLContext(canvas);      initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE);      var a_Position = gl.getAttribLocation(gl.program, 'a_Position');      gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0);      var u_FragColor =gl.getUniformLocation(gl.program,'u_FragColor');      gl.uniform4f(u_FragColor,1.0, 0.0, 0.0, 1.0);      gl.clearColor(0.0, 0.0, 0.0, 1.0);//清除canvas背景色      gl.clear(gl.COLOR_BUFFER_BIT);//清除canvas      gl.drawArrays(gl.POINTS, 0, 1);}

存储限定符

WebGL着色器里面有两种存储限定符 , 放在变量类型前面 , 用于js代码向着色器代码传值.

  • attribute : 用来传输顶点相关的数据.
  • uniform : 用来传输对于所有顶点全部相同的数据(或与顶点无关的数据).

WebGL可以绘制的基本图形

WebGL通过gl.drawArrays()函数可以绘制一些基本图形,接收的参数如下 :

  • 点 (gl . POINTS)
  • 线段 (gl . LINES)
  • 线条 (gl . LINE_STRIP)
  • 回路 (gl . LINE_LOOP)
  • 三角形 (gl . TRIANGLES)
  • 三角带(gl . TRIANGLE_STRIP)
  • 三角扇(gl . TRIANGLE_FAN)
//绘制一个三角形var VSHADER_SOURCE =  'attribute vec4 a_Position;\n' +  'void main() {\n' +  '  gl_Position = a_Position;\n' +  '}\n';var FSHADER_SOURCE =  'void main() {\n' +  '  gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +  '}\n';function main() {      var canvas = document.getElementById('webgl');      var gl = getWebGLContext(canvas);      initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)      var n = initVertexBuffers(gl);      gl.clearColor(0, 0, 0, 1);      gl.clear(gl.COLOR_BUFFER_BIT);      //参数决定了最终画出三角形长什么样.      gl.drawArrays(gl.TRIANGLES, 0, n);}function initVertexBuffers(gl) {      var vertices = new Float32Array([            0, 0.5,   -0.5, -0.5,   0.5, -0.5      ]);      var n = 3;       //利用缓冲区传输顶点,一次性传输多个顶点到缓冲区.      var vertexBuffer = gl.createBuffer();      if (!vertexBuffer) {        console.log('Failed to create the buffer object');        return -1;      }      gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);      gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);      var a_Position = gl.getAttribLocation(gl.program, 'a_Position');      if (a_Position < 0) {        console.log('Failed to get the storage location of a_Position');        return -1;      }      gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);      gl.enableVertexAttribArray(a_Position);      return n;}

varying修饰符和内插

  • varying被用来用来顶点着色器与片元着色器之间的传值 .
//只写出了着色器代码,只要在片元着色器定义一个用varying修饰的同名变量即可.var VSHADER_SOURCE =  'attribute vec4 a_Position;\n' +  'attribute vec4 a_Color;\n' +  'varying vec4 v_Color;\n' + // varying variable  'void main() {\n' +  '  gl_Position = a_Position;\n' +  '  gl_PointSize = 10.0;\n' +  '  v_Color = a_Color;\n' +  // Pass the data to the fragment shader  '}\n';// Fragment shader programvar FSHADER_SOURCE =  '#ifdef GL_ES\n' +  'precision mediump float;\n' + // Precision qualifier (See Chapter 6)  '#endif GL_ES\n' +  'varying vec4 v_Color;\n' +    // Receive the data from the vertex shader  'void main() {\n' +  '  gl_FragColor = v_Color;\n' +  '}\n';

纹理映射

var VSHADER_SOURCE =    'attribute vec4 a_Position;\n' +    'attribute vec2 a_TexCoord;\n' +    'varying vec2 v_TexCoord;\n' +    'void main() {\n' +    '  gl_Position = a_Position;\n' +    '  v_TexCoord = a_TexCoord;\n' +    '}\n';// Fragment shader programvar FSHADER_SOURCE =    '#ifdef GL_ES\n' +    'precision mediump float;\n' +    '#endif\n' +    'uniform sampler2D u_Sampler;\n' +    'varying vec2 v_TexCoord;\n' +    'void main() {\n' +    '  gl_FragColor = texture2D(u_Sampler, v_TexCoord);\n' +    '}\n';function main() {      // Retrieve <canvas> element      var canvas = document.getElementById('webgl');      // Get the rendering context for WebGL      var gl = getWebGLContext(canvas);      if (!gl) {        console.log('Failed to get the rendering context for WebGL');        return;      }      // Initialize shaders      if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {        console.log('Failed to intialize shaders.');        return;      }      // Set the vertex information      var n = initVertexBuffers(gl);      if (n < 0) {        console.log('Failed to set the vertex information');        return;      }      // Specify the color for clearing <canvas>      gl.clearColor(0.0, 0.0, 0.0, 1.0);      // Set texture      if (!initTextures(gl, n)) {        console.log('Failed to intialize the texture.');        return;      }}function initVertexBuffers(gl) {      var verticesTexCoords = new Float32Array([        // Vertex coordinates, texture coordinate            -0.5,  0.5,   0.0, 1.0,            -0.5, -0.5,   0.0, 0.0,            0.5,  0.5,   1.0, 1.0,            0.5, -0.5,   1.0, 0.0,      ]);      var n = 4; // The number of vertices      // Create the buffer object      var vertexTexCoordBuffer = gl.createBuffer();      // Bind the buffer object to target      gl.bindBuffer(gl.ARRAY_BUFFER, vertexTexCoordBuffer);      gl.bufferData(gl.ARRAY_BUFFER, verticesTexCoords, gl.STATIC_DRAW);      var FSIZE = verticesTexCoords.BYTES_PER_ELEMENT;      //Get the storage location of a_Position, assign and enable buffer      var a_Position = gl.getAttribLocation(gl.program, 'a_Position');      gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, FSIZE * 4, 0);      gl.enableVertexAttribArray(a_Position);  // Enable the assignment of the buffer object      // Get the storage location of a_TexCoord      var a_TexCoord = gl.getAttribLocation(gl.program, 'a_TexCoord');      // Assign the buffer object to a_TexCoord variable      gl.vertexAttribPointer(a_TexCoord, 2, gl.FLOAT, false, FSIZE * 4, FSIZE * 2);      gl.enableVertexAttribArray(a_TexCoord);  // Enable the assignment of the buffer object      return n;    }    function initTextures(gl, n) {      var texture = gl.createTexture();   // Create a texture object      if (!texture) {        console.log('Failed to create the texture object');        return false;      }      // Get the storage location of u_Sampler      var u_Sampler = gl.getUniformLocation(gl.program, 'u_Sampler');      if (!u_Sampler) {        console.log('Failed to get the storage location of u_Sampler');        return false;      }      var image = new Image();  // Create the image object      if (!image) {        console.log('Failed to create the image object');        return false;      }      // Register the event handler to be called on loading an image      image.onload = function(){ loadTexture(gl, n, texture, u_Sampler, image); };      // Tell the browser to load an image      image.src = '../resources/sky.JPG';      return true;}function loadTexture(gl, n, texture, u_Sampler, image) {      gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, 1); // Flip the image's y axis      // Enable texture unit0      gl.activeTexture(gl.TEXTURE0);      // Bind the texture object to the target      gl.bindTexture(gl.TEXTURE_2D, texture);      // Set the texture parameters      gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);      // Set the texture image      gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, image);      // Set the texture unit 0 to the sampler      gl.uniform1i(u_Sampler, 0);      gl.clear(gl.COLOR_BUFFER_BIT);   // Clear <canvas>      gl.drawArrays(gl.TRIANGLE_STRIP, 0, n); // Draw the rectangle}