WebGL简介

简介: WebGL简介

前言


HTML的<canvas>元素为JavaScript提供了动态创建图形的API。这些图形需要使用特定上下文绘制,主要有两种:


第一种是Canvas,一般只能做2d操作,用canvas.getContext(“2d”)来建立一个CanvasRenderingContext2D二维渲染上下文。

第二种是WebGL,通过canvas.getContext(‘webgl’)就能获取WebGL的3d上下文,进行3D的渲染。


1. WebGL简介


1.1 WebGL概述


WebGL,是一项用来在网页上绘制和渲染复杂三维图形,并允许用户与之进行交互的技术。WebGL通过JavaScript操作OpenGL接口的标准,把三维空间图像显示在二维的屏幕上。


1.2 WebGL程序的结构


相对于传统网页,支持WebGL的浏览器底层接入了OpenGL/OpenGL ES标准,WebGL通过实现标准支持着色器语言编程语言GLSL ES,在我们实际开发过程中,GLSL ES通常是以字符串的形式存在JavaScript中,我们可以通过JavaScript修改GLSL ES字符串来改变着色器程序。



1.3 WebGL和OpenGL


OpenGL是一种用于渲染2D、3D矢量图形的跨语言、跨平台的应用程序编程接口,是在个人计算机上使用最广泛的两种三维图形渲染技术之一,另一种是Direct3D。在某种意义上,WebGL就是“Web版的OpenGL”。

OpenGL ES在添加新特性的同时从OpenGL中移除了许多陈旧无用的就特性,使得在保持轻量级的同时,仍然具有足够的能力来渲染出精美的三维图形。

WebGL的技术规范继承自OpenGL ES,从2.0版本开始,OpenGL支持可编程着色器方法,这个支持可以让我们通过着色器语言编写着色器程序。


2. 着色器语言


着色器是WebGL依赖的实现图像渲染的一种绘图机制。WebGL在GPU中运行,因此需要使用能够在GPU上运行的代码,这样的代码需要提供成对的方法,他们分别是顶点着色器和片元着色器,可以简单理解为一个定位置一个添颜色。


2.1 顶点着色器


顶点着色器的作用是计算顶点的位置。根据计算出的一系列顶点位置,WebGL可以对点, 线和三角形在内的一些图元进行光栅化处理。

//顶点着色器
const VERTEX_SHADER_SOURCE = `
  // 所有着色器都有一个main方法
  void main() {
    gl_Position = vec4(0.0, 0.0, 0.0, 1.0);//设置坐标
    gl_PointSize = 10.0;//设置尺寸
  }  
`

其中,gl_Position和gl_PointSize是着色器的内置变量,分别代表顶点的位置和大小,因此这段代码的作用是设置顶点的位置和大小。

在着色器内,一般命名以gl_开头的变量是着色器的内置变量。


2.2 片元着色器


片段着色器的作用是计算出当前绘制图元中每个像素的颜色值,逐片元控制片元的颜色和纹理等渲染。

//片元着色器
const FRAGMENT_SHADER_SOURCE = `
  void main() {
    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);//设置颜色
  }   
`

内置变量gl_FragColor来确定顶点像素颜色,vec4是一个四维向量,用来表示一个 RGBA 颜色值,它与 CSS 的颜色区别是,CSS 的 RGB 值是 0 到 255,Alpha 值是 0 到 1,但是在着色器里面,RGBA 的值都是从 0 到 1。


3. webGL绘制一个点


webgl会有大量的重复性前置工作,也就是创建着色器 -> 传入着色器代码 -> 编译着色器 -> 创建着色器程序 -> 绑定、连接、启用着色器 -> 进行绘制。

创建着色器的代码一般封装好了直接调用就行,如下所示:


//gl代表渲染上下文,VERTEX_SHADER_SOURCE代表顶点着色器代码,FRAGMENT_SHADER_SOURCE代表片元着色器代码
function initShader (gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE) {
  // 创建着色器
    const vertexShader = gl.createShader(gl.VERTEX_SHADER);
    const fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
  // 指定着色器对象的代码
    gl.shaderSource(vertexShader, VERTEX_SHADER_SOURCE);
    gl.shaderSource(fragmentShader, FRAGMENT_SHADER_SOURCE);
    //编译着色器
    gl.compileShader(vertexShader);
    gl.compileShader(fragmentShader);
    //创建程序对象
    const program = gl.createProgram();
  // 为程序对象分配顶点着色器和片元着色器
    gl.attachShader(program, vertexShader);
    gl.attachShader(program, fragmentShader);
  // 连接program指定的程序对象中的着色器
    gl.linkProgram(program);
    //告知WebGL系统绘制时使用program指定的程序对象
    gl.useProgram(program);
    return program;
}

绘制点的完整代码

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./initShader.js"></script>
</head>
<body>
  <canvas id="canvas" width="400" height="400">
    不支持canvas
  </canvas>
</body>
<script>
  //获取<canvas>元素
  const ctx = document.getElementById('canvas')
  //获取WebGL绘图上下文
  const gl = ctx.getContext('webgl')
  //顶点着色器
  const VERTEX_SHADER_SOURCE = `
    void main() {
      gl_Position = vec4(0.0, 0.0, 0.0, 1.0);
      gl_PointSize = 10.0;
    }  
  `
  //片元着色器
  const FRAGMENT_SHADER_SOURCE = `
    void main() {
      gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);
    }   
  `
  //创建着色器
  const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
  //执行绘制
  gl.drawArrays(gl.POINTS, 0, 1)
</script>
</html>

效果


整个绘制流程如下所示:


程序的执行流程如下:

首先运行JavaScript程序,调用WebGL相关方法,然后顶点着色器和片元着色器就会执行,在颜色缓冲区内进行绘制,并且清空绘图区,最后颜色缓冲区的内容会自动在浏览器的canvas上显示出来。


4. webGL渲染过程


webGL渲染管线,其实就是图形的渲染过程。

渲染管线主要包括两个功能:一是将物体 3D 坐标转变为屏幕空间 2D 坐标,二是为屏幕每个像素点进行着色,渲染管线的一般流程如下图所示,分别是:顶点处理、裁剪和图元组装、光栅化、片元处理。


1.顶点处理


顶点处理是针对存储于顶点缓冲区的各个输入顶点进行操作,此阶段为可编程状态。主要的操作是对顶点进行坐标转换,把对象由其所定义的坐标系下的表示,转化为照相机下的坐标系。


2.裁剪和图元组装


在顶点处理完之后,就需要将顶点组合成一个个单元,这个单元就是我们的图元。这一步就是组装,将顶点组合成一个个单元,如点,线,三角形。

裁剪则是指将视口以外的片元进行裁剪。


3.光栅化


完成图元组装和裁剪后,下一步是光栅化。

光栅化是将几何图元转化为图像的过程。光栅化主要目的是为了将图元组装和裁剪之后的图元数据转化生成帧缓存中的像素。但是光栅化处理完之后,我们并没有直接得到像素,而是得到了片元。片元是一个像素大小的基本单位,但是它并非像素,而是像素的前身。片元相比于像素,除了 RGBA 之外,还会包含如深度值,法线,纹理坐标等信息。


4.片元处理


片元处理,主要是通过片元着色器,计算片元的最终颜色和深度。

光栅化后,程序调用片元着色器,假定光栅化后有10个片元,那么片元着色器将执行10次,每次调用处理一个片元,片元着色器计算该片元的颜色并写入颜色缓冲区,当最后一个片元被处理完成,浏览器就会显示出最终的结果。

相关文章
|
缓存 开发者 CDN
CDN访问异常篇之重定向的次数过多
用户配置了阿里云CDN或者全站加速后,使用浏览器进行访问,出现重定向的次数过多的错误。
14773 0
CDN访问异常篇之重定向的次数过多
|
8月前
|
域名解析 网络协议 CDN
怎么使用CDN给你的网站加速?
本文介绍阿里云CDN开通与配置全流程:先开通服务,添加加速域名并设置源站信息,再通过CNAME解析绑定域名。完成配置后,通过ping命令验证CNAME生效情况,实现网站加速。
|
测试技术
升级电脑内存
升级电脑内存
805 2
|
存储 搜索推荐 Python
用 Python 实现快速排序算法。
快速排序的平均时间复杂度为$O(nlogn)$,空间复杂度为$O(logn)$。它在大多数情况下表现良好,但在某些特殊情况下可能会退化为最坏情况,时间复杂度为$O(n^2)$。你可以根据实际需求对代码进行调整和修改,或者尝试使用其他优化策略来提高快速排序的性能
438 61
|
安全 Java
java调用方法
java调用方法
245 4
|
机器学习/深度学习 传感器 机器人
机器人策略学习的Game Changer?伯克利提出Body Transformer
【9月更文挑战第13天】加州大学伯克利分校的研究团队提出了一种名为Body Transformer(BoT)的创新架构,旨在通过将机器人的物理形态建模为传感器和执行器组成的图,并利用掩码注意力机制汇聚信息,为机器人学习策略提供有效归纳偏置。BoT不仅在模仿学习和强化学习中表现出色,在任务完成、缩放特性及计算效率方面超越传统架构,而且具备更强的稳定性和泛化能力。尽管存在适用范围和计算资源等局限性,BoT仍展示了在实际应用中的巨大潜力。论文详情见:https://arxiv.org/pdf/2408.06316v1
207 6
|
XML JSON Java
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
本文介绍了如何使用IntelliJ IDEA和Maven搭建一个整合了Struts2、Spring4、Hibernate4的J2EE项目,并配置了项目目录结构、web.xml、welcome.jsp以及多个JSP页面,用于刷新和学习传统的SSH框架。
614 0
使用IDEA+Maven搭建整合一个Struts2+Spring4+Hibernate4项目,混合使用传统Xml与@注解,返回JSP视图或JSON数据,快来给你的SSH老项目翻新一下吧
|
存储 测试技术 开发工具
内核维护者手册 - 变基和合并【ChatGPT】
内核维护者手册 - 变基和合并【ChatGPT】
|
弹性计算 缓存 安全
阿里云服务器2核4G配置租用费用和ECS实例规格性能参数表
阿里云 2核4GB ECS实例提供多样规格,如突发性能t6、经济型e、计算型c7/c6/c8i/c8a/c7a、通用算力型u1等,价格从68元/月至203元/月不等。通用算力u1与经济型e实例分别采用Intel Xeon 8163/8269CY与可扩展系列处理器,支持1万IOPS与最高25万连接数。2核4GB服务器支持约20人同时在线访问,实际并发数受软件效率、带宽、应用架构等因素影响。

热门文章

最新文章