03.drawArrays-绘制其他平面图形

lxf2023-07-06 15:40:01

全部章节

01.shader-最简单的webgl程序

02.buffer-在一个着色器程序中绘制多个点

03.drawArrays-绘制其他平面图形

04.drawElements-绘制一个正方体

05.texture-使用材质贴图

06.frameBuffer-将webgl绘制的正方体作为材质

绘制直线

上章我们学会了给着色器程序传值的一种方式,并存放多个点的数据在缓冲区,一次性绘制多个点。 本章我们沿用上章的程序,做简单的修改来讲解如何在webgl中绘制其他的图形。

效果

03.drawArrays-绘制其他平面图形

代码

<canvas id="cvs" style="width: 400px; height: 400px" height="400px" width="400px"></canvas>
<script src="./03customApi.js"></script>

<script>
  const VS = `
    attribute vec4 a_Position;
    attribute vec4 a_Color;
    varying vec4 v_Color;
    void main() {
      gl_Position = a_Position;
      gl_PointSize = 10.0;
      v_Color = a_Color;
    }
  `;

  const FS = `
    #ifdef GL_ES
    precision mediump float;
    #endif
    varying vec4 v_Color;
    void main() {
      gl_FragColor = v_Color;
    }
  `;
</script>

<script>
  const cvs = document.getElementById('cvs')
  const gl = cvs.getContext('webgl')
  initShader(gl, VS, FS)
  const n = bindBuffer(gl, [
    {
      name: 'a_Position',
      size: 3,
      type: gl.FLOAT,
      stride: 6,
      offset: 0
    },
    {
      name: 'a_Color',
      size: 3,
      type: gl.FLOAT,
      stride: 6,
      offset: 3
    },
  ], new Float32Array([
    -0.5, 0.0, 0.0,   1.0, 0.0, 0.0,
    0.0, 0.0, 0.0,    0.0, 1.0, 0.0,
    0.5, 0.0, 0.0,    0.0, 0.0, 1.0,
    0.75, 0.5, 0.0,    0.0, 0.0, 1.0,
  ]))
  gl.clearColor(1.0, 1.0, 1.0, 1.0)
  gl.clear(gl.COLOR_BUFFER_BIT)
  gl.drawArrays(gl.LINES, 0, n)
</script>

解释

gl_PointSize只有在gl.POINTS的绘制模式下才有效,该程序中无效,线看不太清,就改成白色了。
把bindBuffer的实现放在customApi.js中了。然后多加了一个点的信息。

drawArrays的第一个参数

drawArrays的第二个参数和第三个参数上章讲过了,起始绘制点和总绘制的点数。

本章主要就是围绕的是drawArrays的第一个参数。 第一个参数是绘制的方式,我们看一下有哪些值

  1. gl.POINTS: 绘制一系列点。
  2. gl.LINES: 绘制一系列单独线段。每两个点作为端点,线段之间不连接。
  3. gl.LINE_STRIP: 绘制一个线条。即,绘制一系列线段,上一点连接下一点。
  4. gl.LINE_LOOP: 绘制一个线圈。即,绘制一系列线段,上一点连接下一点,并且最后一点与第一个点相连。
  5. gl.TRIANGLES: 绘制一系列三角形。每三个点作为顶点。
  6. gl.TRIANGLE_STRIP:绘制一个三角带。
  7. gl.TRIANGLE_FAN:绘制一个三角扇。

第一个就是绘制一个个点,之前两章一直在使用。 本例中使用了第二个,绘制多个线段,接下来我们依次介绍每种绘制方式的特点。

gl.POINTS

绘制点,根据first和count的值获取缓冲区存在的对应数量的点,并绘制,如果缓冲区的点数量不够就会报错

03.drawArrays-绘制其他平面图形

gl.LINES

绘制线段,和绘制点差不多,同样缓存区的点的数量不够会报错。
不一样的是,如果绘制的点数量为奇数,会忽略最后一个点03.drawArrays-绘制其他平面图形

从结果中,我们两个点之间的颜色会根据两个点的颜色去渐变
当然也有办法阻止这样的渐变,可以利用gl_FragCoord或者gl_PointCoord这两个内置变量去处理,简单理解为一个是像素点的位置,一个片元坐标。

我们把片元着色器中的
gl_FragColor = v_Color;
替换成
gl_FragColor = gl_PointCoord.x < -0.25 ? vec4(1.0,0.5,0.5,1.0) : v_Color;
然后查看第一条线段的变化

03.drawArrays-绘制其他平面图形

同样我们用图来直观的理解一下LINES 03.drawArrays-绘制其他平面图形

gl.LINE_STRIP

连续绘制线段,第一个点和第二个点相连,第二个点和第三个点相连,以此类推,颜色规律也是两点的颜色渐变

03.drawArrays-绘制其他平面图形

gl.LINE_LOOP

连续绘制线段,第一个点和第二个点相连,第二个点和第三个点相连,最终第一个点和最后一个点相连,颜色规律也是两点的颜色渐变

03.drawArrays-绘制其他平面图形

gl.TRIANGLES

每三个点绘制一个三角形,多出来的少于三个的点忽略,颜色规律是三个点之间的渐变
当前程序中的四个点,无法绘制三角形,因为前三个点处于一条直线,无法形成三角形,但是我们可以把frist改成1,count改成3,用后三个点绘制。 不过为了更好的演示后面的绘制模式,我们将输入的四个点改成另外的六个点

0, -0.5, 0.0,      1.0, 0.0, 0.0, // 红色
0.5, 0, 0.0,       0.0, 1.0, 0.0, // 绿色
0.25, 0.25, 0.0,   0.0, 0.0, 1.0, // 蓝色
0, 0.8, 0.0,       1.0, 1.0, 0.0, // 黄色
-0.5, -0.5, 0.0,   0.0, 1.0, 1.0, // 淡蓝
-0.5, -0.8, 0.0,   1.0, 0.0, 1.0 // 紫色

03.drawArrays-绘制其他平面图形

gl.TRIANGLE_STRIP

连续绘制三角形,0,1,2形成第一个三角形,1,2,3形成第二个三角形,2,3,4形成第三个三角形,一直到最后不满足三个点。

03.drawArrays-绘制其他平面图形

由于每个点设置的颜色不同,所以每个三角形都是渐变色的,最终连续的绘制导致结果如上图,不是很清晰。
我们使用drawElements,利用gl.TRIANGLES去模拟gl.TRIANGLE_STRIP的绘制行为。

drawElements具体会在下一章讲解,本章中仅展示一个用gl.TRIANGLES模拟的结果,让大家更好的去理解。

03.drawArrays-绘制其他平面图形

6个点,通过模拟可以看出最终绘制出了4个三角形。 我们在使用gl.POINTS,直观的看一下6个点的位置

03.drawArrays-绘制其他平面图形

gl.TRIANGLE_FAN

绘制三角扇,即第一个点和每两个连续点绘制一个三角形,比如说上述六个点,1,2,3绘制一个三角形,1,3,4绘制一个三角形,1,4,5绘制一个三角形,1,5,6绘制一个三角形。

03.drawArrays-绘制其他平面图形

结果还是看不太清楚,我们看一下模拟的结果

03.drawArrays-绘制其他平面图形

总结

本章基于上章的程序上,仅对点的数据和drawArrays的入参做修改,详细了解了webgl中的七种绘制模式,以及drawArrays这个API。
在我们实际使用中,最常用的绘制模式就是gl.TRIANGLES,就像经常听到的每个模型都是由三角面组成的,本章中对于TRIANGLE_STRIP和TRIANGLE_FAN的模拟也是通过TRIANGLES实现的,实现的方法会在下一章中涉及到。

相关代码gitee

本网站是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 本网站还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 除此之外,本网站还拥有一个活跃的社区,您可以在社区中与其他前端开发者交流技术、分享经验、解决问题。我们相信,社区的力量可以帮助您更好地成长和进步。 在本网站中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!