关于javascript:JavaScript-WebGL-绘制一个面

5次阅读

共计 2709 个字符,预计需要花费 7 分钟才能阅读完成。

引子

JavaScript WebGL 根底纳闷点之后进行了一些优化,而后尝试绘制常见二维的面。

WebGL 中几何体最终都是由三角形形成,由三角形切入比拟适合。

  • Origin
  • My GitHub

绘制三角形

这是示例,基于绘制一条直线次要的变动有:

  • 顶点
  • 绘制图元

顶点

三角形有三个顶点,在根底纳闷点中晓得坐标系是右手坐标系,集体习惯形容顶点的程序以图形核心为原点,从第一象限到第四象限。

  let vertices = [
    0.5, 0.5, 0.0, // 第一象限
    -0.5, 0.5, 0.0, // 第二象限
    -0.5, -0.5, 0.0, // 第三象限
  ]; // 三角形 

绘制图元

这次绘制的是一个面,drawArrays 中绘制模式变为 gl.TRIANGLES。顺便看看图元的几种模式。

  • gl.POINTS:绘制一系列点。
  • gl.LINES:绘制一系列独自线段,每两个点作为端点,线段之间不连贯。例如有顶点 A、B、C、D、E、F,就会失去了三条线段。

  • gl.LINE_STRIP:绘制一系列线段,上一点连贯下一点。

  • gl.LINE_LOOP:绘制一系列线段,上一点连贯下一点,并且最初一点与第一个点相连。

  • gl.TRIANGLES:绘制一系列三角形,每三个点作为顶点。例如有 6 个顶点 A、B、C、D、E、F,就会绘制 2 个三角形:ABC 和 DEF。

  • gl.TRIANGLE_STRIP:用来绘制有共享边的三角形。从第二个三角形开始,每次读取一个顶点,并利用后面的开端两个顶点形成一个三角形,以此类推。例如有 6 个顶点 A、B、C、D、E、F,就会绘制 4 个三角形:ABC 和 BCD 和 CDE 和 DEF。

  • gl.TRIANGLE_FAN:绘制有共享边的三角形。从第二个三角形开始,每次读取一个顶点,并利用首个顶点和之前最初一个顶点来形成一个三角形,以此类推。例如有 6 个顶点 A、B、C、D、E、F,就会绘制 4 个三角形:ABC 和 ACD 和 ADE 和 AEF。

执行过程

这里有一个绘制三角形执行过程可视化,联合看看有助于加深了解。

高清解决

下面的示例,在高清屏幕中会呈现显著的含糊和锯齿,但跟解决 2d 上下文的含糊又有些不一样。最次要的一个区别是 WebGL 中须要用 viewport 办法指定从规范设施到窗口坐标的映射变换。具体能够见这篇文章外面的解释。

这是高清示例。

  function WebGLHD(w = 300, h = 150) {
    const ratio = window.devicePixelRatio || 1;
    const canvas = document.createElement("canvas");
    const context = canvas.getContext("webgl");
    // 高清屏幕含糊问题解决
    canvas.width = w * ratio; // 理论渲染像素
    canvas.height = h * ratio; // 理论渲染像素
    canvas.style.width = `${w}px`; // 管制显示大小
    canvas.style.height = `${h}px`; // 管制显示大小
    context.viewport(0, 0, context.canvas.width, context.canvas.height);
  }

绘制矩形

后面有说 WebGL 中几何体最终都是由三角形形成,在绘制多边形的时候须要合成为多个三角形。

这是示例,一个矩形能够分为两个三角形:

  let vertices = [
    0.5, 0.5, 0.0,
    -0.5, 0.5, 0.0,
    -0.5, -0.5, 0.0, // 第一个三角形
    -0.5, -0.5, 0.0,
    0.5, -0.5, 0.0,
    0.5, 0.5, 0.0, // 第二个三角形
  ]; // 矩形 

能够发现有一条边是公共,这个时候能够索引缓冲区对象缩小冗余的数据。

索引缓冲对象

索引缓冲对象全称是 Index Buffer Object(IBO),通过索引的形式复用已有的数据。

基于下面正方形的示例,次要的变动有以下几方面:

  • 数据
  • 缓冲
  • 绘制

数据

顶点地位数据只须要 4 个就足够了,公共数据应用索引代替。

  const vertices = [
    0.5, 0.5, 0.0, // 第 1 个顶点
    -0.5, 0.5, 0.0, // 第 2 个顶点
    -0.5, -0.5, 0.0, // 第 3 个顶点
    0.5, -0.5, 0.0, // 第 4 个顶点
  ]; // 矩形 

索引数据跟下面提醒到的图元绘制模式无关。

绘制模式为 gl.TRIANGLES 时,两个三角形是独立的,索引数据如下:

const indexData = [
  0, 1, 2, // 对应顶点地位数据中 1、2、3 顶点的索引
  0, 2, 3, // 对应顶点地位数据中 1、3、4 顶点的索引
]

绘制模式为 gl.TRIANGLE_STRIP 时,利用前一个三角形开端的两个顶点构建三角形:

const indexData = [1, 0, 2, 3 // 绘制时,先取索引 1、0、2 的地位数据绘制第一个三角形,而后再取索引 0、2、3 的地位数据 绘制第二个三角形]

绘制模式为 gl.TRIANGLE_FAN 时,利用第一个顶点,和前一个三角形开端的一个顶点,加上新读取的顶点构建三角形:

const indexData = [0, 1, 2, 3 // 绘制时,先取索引 0、1、2 的地位数据绘制第一个三角形,而后再取索引 0、2、3 的地位数据 绘制第二个三角形]

缓冲

索引的数据须要缓冲到对应的变量能力应用。

/**
 * 缓冲索引数据
 * @param {*} gl WebGL 上下文
 * @param {*} data 索引数据
 */
function setIndexBuffers(gl, data) {
  // 创立空白的缓冲对象
  const buffer = gl.createBuffer();
  // 绑定指标
  gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, buffer);
  // WebGL 不反对间接应用 JavaScript 原始数组类型,须要转换
  const dataFormat = new Uint16Array(data);
  // 初始化数据存储
  gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, dataFormat, gl.STATIC_DRAW);
}

绘制

应用了索引缓冲对象,须要用 drawElements 办法来代替 drawArrays。该办法多了一个 type 参数,指的是索引缓冲数据的类型,有上面的值可取:

  • gl.UNSIGNED_BYTE
  • gl.UNSIGNED_SHORT

后面缓冲索引数据类型转换为了 Uint16Array,这里应该应用 gl.UNSIGNED_SHORT

三种形式示例如下:

  • TRIANGLES 示例
  • TRIANGLE_STRIP 示例
  • TRIANGLE_FAN 示例

参考资料

  • WebGL 根底绘制之二:绘制三角形
  • WebGL lessons
  • 你好,三角形
  • WebGL 1.0 官网索引卡片
正文完
 0