关于webgl:WebGL-及其在-WebRTC-中的应用

6次阅读

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

一、前言

1、什么是 WebGL ?

WebGL 的全称是 Web Graphics Library,是一种 3D 绘图协定。

WebGL 容许把 JavaScript 和 OpenGL ES 2.0 联合在一起,通过减少 OpenGL ES 2.0 的一个 JavaScript 绑定,WebGL 能够为 HTML5 Canvas 提供硬件 3D 减速渲染。Web 开发人员就能够借助零碎显卡来在浏览器里更流畅地展现 3D 场景和模型,还能创立简单的导航和数据视觉化。

2、OpenGL 与 GLSL

在理解 WebGL 之前,咱们需理解下什么是 OpenGL 与 GLSL。

OpenGL(英语:Open Graphics Library,译名为凋谢图形库或者“开放式图形库”)是用于渲染 2D、3D 矢量图形的跨语言、跨平台的应用程序编程接口(API),GLSL 则是用来在 OpenGL 中着色编程的语言。

从上文中能够看到 WebGL 实际上是 JavaScript 操作一些 OpenGL 接口,也就意味着,可能会编写一部分 GLSL ES 2.0 的代码,没错你猜对了,WebGL 只是绑定了一层,外部的一些核心内容,例如着色器、材质、灯光等都是须要借助 GLSL ES 语法来操作的。

基于 WebGL 周边也衍生了泛滥的第三方库,比方开发利用类的 Three.js,开发游戏类的 Egert.js 等,都大大的升高了学习 WebGL 的老本,然而本着有问题解决问题,没问题制作问题再解决问题的程序猿态度,还是感觉应该略微理解一下 WebGL 的一些基本概念,以便能更好的去了解不同框架带来的便捷以及劣势!

二、WebGL 概述

明天还是用 5W1H 分析法,围绕 WebGL 给大家做一下介绍:

1、Who: 谁创造的?

WebGL 起源于 Mozilla 员工弗拉基米尔·弗基西维奇的一项称为 Canvas 3D 的试验我的项目。

2006 年,弗基西维奇首次展现了 Canvas 3D 的原型。

2007 年底在 Firefox 和 Opera 被实现。

在 2009 年初,非营利技术联盟 Khronos Group 启动了 WebGL 的工作组,最后的工作成员包含 Apple、Google、Mozilla、Opera 等。

2011 年 3 月公布 WebGL 1.0 标准。截至 2012 年 3 月,工作组的主席由肯·罗素(Ken Russell,全名“Kenneth Bradley Russell”)负责。

WebGL 的晚期利用包含 Zygote Body。

2、When: 什么时候开始广泛应用?

WebGL 2.0 标准的倒退始于 2013 年,并于 2017 年 1 月实现。该标准基于 OpenGL ES 3.0 产生,首度实现在 Firefox 51、Chrome 56 和 Opera 43 中。市面上除了反人类的 IE 外基本上均反对,兼容性很好。

3、Where: 次要在什么中央(场景)应用?

3D 的数据可视化、3D 游戏开发、H5 广告 / Web 宣传页、图像处理等。

说一下 3D 的数据可视化。3D 的可视化利用技术和视觉感官从信息中提取价值。当咱们剖析典型 2D 格局的数据时,通常由电子表格或统计图中的数字组成,咱们理论能够获取并用于布局,制订决策,定位客户等等的信息是无限的,3D 可视化技术使咱们可能看到在传统的图表看不到的内容。

4、Why: 为什么用它?

WebGL 完满地解决了现有的 Web 交互式三维动画的两个问题:

问题一:它通过 HTML 脚本 自身实现 Web 交互式三维动画的制作,无需任何浏览器插件反对;

问题二:它利用底层的图形硬件加速性能进行的图形渲染,是通过对立的、规范的、跨平台的 OpenGL 接口实现的。

5、How: 怎么应用?

检测浏览器是否反对 WebGL。应用前,能够通过检测页面能够看到 以后应用的浏览器对 WebGL 的反对状况,包含反对的标准版本。

6、对于着色器

WebGL 只关怀两件事:裁剪空间中的坐标值和色彩值。你须要提供两个着色器来做这两件事,一个顶点着色器提供裁剪空间坐标值,一个片断着色器提供色彩值。

顶点着色器的作用是计算顶点的地位。依据计算出的一系列顶点地位,WebGL 能够对点、线和三角形在内的一些图元进行光栅化解决(把顶点数据转换为片元的过程,将图转化为一个个栅格组成的图象)。当对这些图元进行光栅化解决时须要应用片断着色器办法。片断着色器的作用是计算出以后绘制图元中每个像素的色彩值。

1)顶点着色器

// 一个属性值,将会从缓冲中获取数据
attribute vec4 a_position;
 
// 所有着色器都有一个 main 办法
void main() {
 
  // gl_Position 是一个顶点着色器次要设置的变量
  gl_Position = a_position;
}

2)片断着色器

// 片断着色器没有默认精度,所以咱们须要设置一个精度
// mediump 是一个不错的默认值,代表“medium precision”(中等精度)precision mediump float;
 
void main() {
  // gl_FragColor 是一个片断着色器次要设置的变量
  gl_FragColor = vec4(1, 0, 0.5, 1); // 返回“红紫色”}

着色器语言应用的是 GLSL ES 语言,在 JavaScript 中无奈间接执行,须要将之寄存在字符串中,期待调用。

编译着色器中蕴含几个内置变量:gl_Position、gl_PointSize、gl_FragColor。

gl_Position: 为一种 vec4 类型的变量,且必须被赋值。四维坐标矢量,咱们称之为齐次坐标,即 (x,y,z,w),等价于三维坐标 (x/w,y/w,z/w),w 相当于深度,没有特殊要求设置为 1.0 即可;

gl_PointSize: 示意顶点的尺寸,不填则默认显示为 1.0;

gl_FragColor: 示意色彩,是片元着色器中惟一的内置变量,也是一个 vec4 类型变量,别离代表(R、G、B、A),不过色彩范畴是从 0.0-1.0 对应 Javascript 中的 #00-#FF。

三、根本用法

1、创立 WebGL 对象

不同浏览器申明 WebGL 对象形式有所区别,尽管大部分浏览器都反对 experimental-webgl,而且当前会变成 WebGL,所以创立时做一下兼容解决:

var canvas = document.getElementById("glcanvas");
gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");

2、创立顶点着色器

var VSHADER_SOURCE = 
  'void main() {\n' +
    'gl_Position = vec4(0.0, 0.0, 0.0, 1.0);\n' +
    'gl_PointSize = 10.0;\n' + 
  '}\n';

3、创立片元着色器

var FSHADER_SOURCE =
   'void main() {\n' +
   'gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n' +
'}\n';

着色器代码须要载入到一个程序中,WebGL 应用此程序能力调用着色器。

var program = gl.createProgram();
// 创立顶点着色器 
var vShader = gl.createShader(gl.VERTEX_SHADER);
// 创立片元着色器 
var fShader = gl.createShader(gl.FRAGMENT_SHADER);
// shader 容器与着色器绑定 
gl.shaderSource(vShader, VSHADER_SOURCE);
gl.shaderSource(fShader, FSHADER_SOURCE);
// 将 GLSE 语言编译成浏览器可用代码 
gl.compileShader(vShader);
gl.compileShader(fShader);
// 将着色器增加到程序上 
gl.attachShader(program, vShader);
gl.attachShader(program, fShader);
// 链接程序,在链接操作执行当前,能够任意批改 shader 的源代码,// 对 shader 从新编译不会影响整个程序,除非从新链接程序 
gl.linkProgram(program);
// 加载并应用链接好的程序 
gl.useProgram(program);

接着绘制一个点:

gl.clearColor(0.0,0.0,0.0,1.0); 
gl.clear(gl.COLOR_BUFFER_BIT); 
gl.drawArrays(gl.POINTS, 0 ,1);

四、美颜滤镜

咱们曾经理解了 WebGL 的一些基本概念和根本应用办法,上面咱们将介绍 WebGL 的图像处理及其如何使用到 WebRTC。

要想做到例如美白、红润等成果,咱们须要把握大量的 WebGL 常识和图像算法,本次分享先让大家对滤镜有一个初步的意识,了解如何绘制图片。

图像处理

在 WebGL 中绘制图片须要应用纹理,和 WebGL 渲染时须要裁剪空间坐标类似,渲染纹理时须要纹理坐标,而不是像素坐标。无论纹理是什么尺寸,纹理坐标范畴始终是 0.0 到 1.0。

因为咱们只用画一个矩形(其实是两个三角形),所以须要通知 WebGL 矩形中每个顶点对应的纹理坐标。咱们将应用一种非凡的叫做 varying 的变量将纹理坐标从顶点着色器传到片断着色器,它叫做“可变量”是因为它的值有很多个,WebGL 会用顶点着色器中的值进行插值,而后传给对应像素执行的片断着色器。

attribute vec2 a_texCoord;
...
varying vec2 v_texCoord;
 
void main() {
   ...
   // 将纹理坐标传给片断着色器
   // GPU 会在点之间进行插值
   v_texCoord = a_texCoord;
}
<script id="fragment-shader-2d" type="x-shader/x-fragment">
precision mediump float;
 
// 纹理
uniform sampler2D u_image;
 
// 从顶点着色器传入的纹理坐标
varying vec2 v_texCoord;
 
void main() {
   // 在纹理上寻找对应色彩值
   gl_FragColor = texture2D(u_image, v_texCoord);
}
</script>

1、增加滤镜

增加滤镜的关键点在于 shader(着色器),在片元着色器中咱们能够看到这样一段代码:

void main() {
   // 在纹理上寻找对应色彩值
   gl_FragColor = texture2D(u_image, v_texCoord);
}

这里 texture2D(u_image, v_texCoord) 代表着图像解析后的 RGBA 值,当咱们间接赋值给 gl_FragColor 时则原图输入,那么滤镜的外围也就在这里,咱们须要对其进行改写,上面咱们先从最简略的灰度滤镜成果做例子,从 RGB 色转为灰度色的算法咱们能够很简略的从网上找出,这里取其中一种 Gray = R0.299 + G0.587 + B*0.114,理论使用如下:

void main () {vec4 color = texture2D(u_image, v_texCoord);
    float gray = 0.2989*color.r+0.5870*color.g+0.1140*color.b;
    gl_FragColor = vec4(gray,gray,gray , color.a);
}

2、传输到 WebRTC

在实现滤镜后,又该如何将其传输到 WebRTC 中呢?

有的同学应用过 WebRTC 会晓得 WebRTC 的传输离不开媒体流(MediaStream),MediaStream 是一个媒体内容的流,一个流蕴含几个轨道,比方视频和音频轨道。

后面咱们提到了,WebGL 的应用是在 canvas 中进行的,咱们能够通过 canvas 的 caputureStream API 获取到 mediaStream 对象,获取后即可进行传输。

五、结尾

通过上述的学习,置信大家对 WebGL 的概念有了肯定的理解。当然,要想实现简单的美颜滤镜成果还有很多内容须要学习。

此外,即构在 Web 端提供了成熟的美颜性能,只需简略几步,即可实现不同的美颜成果,感兴趣的同学能够通过链接理解更多:[https://doc-zh.zego.im/articl…

正文完
 0