前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WebGL学习笔记 | 使用着色器绘制一个点

WebGL学习笔记 | 使用着色器绘制一个点

作者头像
张晓衡
发布2019-09-11 18:15:27
8040
发布2019-09-11 18:15:27
举报

前一篇 《WebGL学习笔记 | 创建着色器程序》介绍了如何创建着色器程序,这次我们让着色器程序运行起来,并在屏幕上绘制一个点。

1. 顶点着色器程序

完整的着色器程序分为顶点着色器程序片元着色器程序,我们先看下顶点着色器的程序代码,将它定义为一个JavaScript字符串:

代码语言:javascript
复制
//顶点着色器程序
var VSHADER_SOURCE = `
  void main() {
    //设置一个坐标点
    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
    //设置点的大小
    gl_PointSize = 4.0;                    
  }
`

顶点着色器是用来描述顶点特性比如:位置和大小,它是指二维或三维空间中的一个点,顶点着色器中有两个内置变量:

  • gl_Position:表示顶点位置
  • gl_PointSize:表示点的尺寸(像素,默认为1.0)

上面代码中 gl_Position 内置变量必须被赋值,否则着色器就不能正常工作,gl_PointSize 则不是必须的,它的默认值为1.0 。

注意我们给 gl_Position 赋值了一个矢量 vec4 它内部是由 4 个浮点数组成,但是这里只用了三个即:x、y、z,第四个分量设置为 1.0 在这里被称之为齐次坐标,因为它能够提高处理三维数据的效率,所以被三维图形系统大量使用。

当需要使用齐次坐标表示顶点坐标时,只需要将最后一个分量置为 1.0 即可。

齐次坐标:齐次坐标使用(x, y, z, w)表示,等价于三维坐标(x/w, y/w, z/w),所以如果齐次坐标的第 4 个分量是 1,就可以将它当三维坐标使用。

2. 片元着色器程序

片元可以理解为逐像素处理过程,严格意义上说片元还包括:像素的位置、颜色和其它信息。

代码语言:javascript
复制
//片元着色器程序
var FSHADER_SOURCE =`
    void main() {
        //设置点的颜色
        gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }
`;

gl_FragColor 是片元着色器中的唯一内置变量,它控制像素在屏幕上的最终颜色,上面代码中的 vec4 的 4个分量代表颜色的 RGBA 值。

3. 在 JavaScript 启用绘制

在 JavaScript 中初始化好着色器程序,进行编译、链接,最后一步就是进行绘制操作:

代码语言:javascript
复制
//看上一篇《WebGL学习笔记 | 创建着色器程序》中有讲解...
gl.useProgram(program);
gl.drawArrays(gl.POINTS, 0, 1);

gl.drawArrays 函数非常强大,它可以用来绘制各种图形,该函数规范如下:

gl.drawArrays(mode, first, count)


参数 mode:指定绘制方式,可接收以下常量:gl.POINTS、gl.LINES、gl.LINESTRIP、gl.LINELOOP、gl.TRIANGLES、gl.TRIANGLESTRIP、gl.TRIANGLEFAN first:指定从那个顶点开始绘制(整型数) count:指定绘制需要用到多少个顶点(整型数) 返回值:错误: INVALID_ENUM 传入的 mode 参数不是前述参数之一 INVALID_VALUE 参数 first 或 count 是负数

使用 gl.drawArrays() 时,顶点着色器将被执行 count 次,每次处理一个顶点,我们这里只绘制了一个点,因此count为1。

当顶点着色器执行完成后,片元着色器开始执行,将颜色值赋给 gl_FragColor,最后一个红色的像素点被绘制到了屏幕的中心位置 (0.0, 0.0, 0.0) ,看下图:

本篇教程完整源码如下:

HelloPoint.html

代码语言:javascript
复制
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Draw a point (1)</title>
  </head>

  <body onload="main()">
    <canvas id="webgl" width="400" height="400">
    Please use a browser that supports "canvas"
    </canvas>

    <script src="HelloPoint1.js"></script>
  </body>
</html>

HelloPoint.js

代码语言:javascript
复制
//顶点着色器代码
var VSHADER_SOURCE = `
  void main() {
    gl_Position = vec4(0.0, 0.0, 0.0, 1.0); 
    gl_PointSize = 8.0;                    
  }
`;

//片元着色器代码
var FSHADER_SOURCE =`
void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
}
`;

//创建着色器程序并绘制
function main() {
  // 获取canvas标签
  var canvas = document.getElementById('webgl');

  // 获取webgl上下文对象
  var gl = canvas.getContext('webgl')//getWebGLContext(canvas);
  if (!gl) {
    console.log('Failed to get the rendering context for WebGL');
    return;
  }

  //创建、编译顶点Shader
  var vertexShader = gl.createShader(gl.VERTEX_SHADER);
  gl.shaderSource(vertexShader, VSHADER_SOURCE);
  gl.compileShader(vertexShader);
  if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
    var error = gl.getShaderInfoLog(vertexShader);
    console.log('Failed to compile shader: ' + error);
    gl.deleteShader(vertexShader);
    return null;
  }

  //创建、编译片元Shader
  var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  gl.shaderSource(fragmentShader, FSHADER_SOURCE);
  gl.compileShader(fragmentShader);
  if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
    var error = gl.getShaderInfoLog(fragmentShader);
    console.log('Failed to compile shader: ' + error);
    gl.deleteShader(vertexShader);
    gl.deleteShader(fragmentShader);
    return null;
  }

  //创建program对象,关联、链接顶点、片元着色器
  var program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);
  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    var error = gl.getProgramInfoLog(program);
    console.log('Failed to link program: ' + error);
    gl.deleteProgram(program);
  }
  //启用有着色器程序
  gl.useProgram(program);
  //通知webgl绘编
  gl.drawArrays(gl.POINTS, 0, 1);
}
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-07-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Creator星球游戏开发社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 顶点着色器程序
  • 2. 片元着色器程序
  • 3. 在 JavaScript 启用绘制
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档