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次,每次调用处理一个片元,片元着色器计算该片元的颜色并写入颜色缓冲区,当最后一个片元被处理完成,浏览器就会显示出最终的结果。

相关文章
|
Linux
Linux:ln创建删除软连接
Linux:ln创建删除软连接
2092 0
|
3月前
|
域名解析 网络协议 CDN
怎么使用CDN给你的网站加速?
本文介绍阿里云CDN开通与配置全流程:先开通服务,添加加速域名并设置源站信息,再通过CNAME解析绑定域名。完成配置后,通过ping命令验证CNAME生效情况,实现网站加速。
|
JSON 前端开发 Java
如何封装接口返回结构?
本文详细探讨了API接口返回结构统一化的必要性及其带来的优势,如降低开发的心智负担、减少前端开发难度和提高代码可维护性等。同时也分析了其潜在的缺点,例如灵活性降低和开发成本增加等问题。文章进一步讨论了在Spring Boot中实现统一接口返回结构的具体方法和技术细节,包括如何处理HTTP状态码、返回单个字符串的情况以及如何封装无返回值的接口等。此外,还介绍了如何利用Spring Boot的`ResponseBodyAdvice`和`@RestControllerAdvice`等特性来自动包装控制器方法的返回值及异常处理,以达到更加一致和标准化的接口响应结构。
308 3
如何封装接口返回结构?
|
6月前
|
存储 关系型数据库 分布式数据库
【赵渝强老师】基于PostgreSQL的分布式数据库:Citus
Citus 是基于 PostgreSQL 的开源分布式数据库,采用 shared nothing 架构,具备良好的扩展性。它以插件形式集成,部署简单,适用于处理大规模数据和高并发场景。本文介绍了 Citus 的基础概念、安装配置步骤及其在单机环境下的集群搭建方法。
515 2
|
存储 SQL 关系型数据库
一篇文章搞懂MySQL的分库分表,从拆分场景、目标评估、拆分方案、不停机迁移、一致性补偿等方面详细阐述MySQL数据库的分库分表方案
MySQL如何进行分库分表、数据迁移?从相关概念、使用场景、拆分方式、分表字段选择、数据一致性校验等角度阐述MySQL数据库的分库分表方案。
一篇文章搞懂MySQL的分库分表,从拆分场景、目标评估、拆分方案、不停机迁移、一致性补偿等方面详细阐述MySQL数据库的分库分表方案
|
算法 数据可视化 数据挖掘
【数据挖掘】密度聚类DBSCAN讲解及实战应用(图文解释 附源码)
【数据挖掘】密度聚类DBSCAN讲解及实战应用(图文解释 附源码)
1416 1
|
缓存 前端开发 JavaScript
阿里云CDN:怎么让网站变快
阿里云CDN:怎么让网站变快
|
缓存 安全 开发工具
程序与技术分享:Directx11学习笔记【三】第一个D3D11程序
程序与技术分享:Directx11学习笔记【三】第一个D3D11程序
1251 0
|
弹性计算 缓存 安全
阿里云服务器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人同时在线访问,实际并发数受软件效率、带宽、应用架构等因素影响。