webgl 基础

2022-08-08 12:41:34 浏览数 (1)

认识 webgl

WebGL仅仅是一个光栅化引擎,它可以根据你的代码绘制出点,线和三角形。 WebGL在电脑的GPU中运行,每对方法中一个叫顶点着色器, 另一个叫片断着色器,并且使用一种和C或C 类似的强类型的语言 GLSL。 每一对组合起来称作一个 program(着色程序)

GLSL全称是 Graphics Library Shader Language (图形库着色器语言),是着色器使用的语言。 它有一些不同于JavaScript的特性,主要目的是为栅格化图形提供常用的计算功能。

webgl 发展

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。

WebGL 2规范的发展始于2013年,并于2017年1月完成。该规范基于OpenGL ES 3.0。首度实现在Firefox 51、Chrome 56和Opera 43中。

webgl的支持(兼容性)

WebGL(Web 图形库)是一个 JavaScript API,可在任何兼容的 Web 浏览器中渲染高性能的交互式 3D 和 2D 图形,而无需使用插件。WebGL 通过引入一个与 OpenGL ES 2.0 非常一致的 API 来做到这一点,该 API 可以在 HTML5"canvas"元素中使用。 这种一致性使 API 可以利用用户设备提供的硬件图形加速。

目前支持 WebGL 的浏览器有:Firefox 4 , Google Chrome 9 , Opera 12 , Safari 5.1 , Internet Explorer 11 和Microsoft Edge build 10240 ;

然而,WebGL 一些特性也需要用户的硬件设备支持。

WebGL 2 API 引入了对大部分的 OpenGL ES 3.0 功能集的支持; 它是通过WebGL2RenderingContext界面提供的。

canvas 元素也被 Canvas API 用于在网页上进行 2D 图形处理。

webgl的优缺点

优点:

    1. WebGL通过HTML脚本本身实现 Web 交互式三维动画的制作,无需任何浏览器插件支持。
    1. WebGL利用底层的图形硬件加速功能进行的图形渲染,是通过统一的、标准的、跨平台的OpenGL接口实现的。

缺点:

    1. 相对于桌面开发API: Unity、 OpenGl、UE这些软件,效果略差
    1. 开发成本高,需要对线性数学和webgl api熟悉
    1. 硬件GPU 显卡要求高

创建webgl

Canvas 是 HTML5 提供的一个特性,你可以把它当做一个载体,简单的说就是一张白纸。而 Canvas 2D 相当于获取了内置的二维图形接口,也就是二维画笔。Canvas 3D 是获取基于 WebGL的图形接口,相当于三维画笔。你可以选择不同的画笔在上面作画。

代码语言:php [2-4|6-8]复制
    // 创建canvas,定宽高

    const canvas = document.querySelector('#canvas');

    canvas.width = window.innerWidth;

    canvas.height = window.innerHeight;

    // 基于canvas创建gl, 设置颜色

    const gl = canvas.getContext('webgl');

    gl.clearColor(0, 0, 0, 1);

    gl.clear(gl.COLOR_BUFFER_BIT);

创建webgl 着色器

shaders:

OpenGL Shading Language

precision :

lowp :精确度低

mediump:精确度中

highp :精确度高

代码语言:php [1-9|11-23]复制
    // 顶点着色器

    const vertexShaderSource = `

      // 设置浮点数据类型为中级精度

      precision mediump float;

      // 接收顶点坐标 (x,y)

      attribute vec2 a_Position;

      void main () {

        gl_Position = vec4(a_Position, 0.0, 1.0);

      }

    `;

    // 创建创建着色器

    const vertexShader = gl.createShader(gl.VERTEX_SHADER);

    //绑定数据源

    gl.shaderSource(vertexShader, vertexShaderSource);

    // 编译着色器

    gl.compileShader(vertexShader);

    // 创建着色器程序

    const program = gl.createProgram()

    gl.attachShader(program, vertexShader)

    gl.attachShader(program, fragmentShader)

    // 链接 并使用着色器

    gl.linkProgram(program)

    gl.useProgram(program)

调试着色器

代码语言:php [1-8|9-11]复制
    const success = gl.getProgramParameter(program, gl.LINK_STATUS)

    if (success) {

    gl.useProgram(program)

    return program

    }

    console.error(gl.getProgramInfoLog(program), 'test---')

    gl.deleteProgram(program)

WebGL 工作原理

WebGL在GPU上的工作基本上分为两部分,第一部分是将顶点(或数据流)转换到裁剪空间坐标, 第二部分是基于第一部分的结果绘制像素点

代码语言:javascript复制
var primitiveType = gl.TRIANGLES;

var offset = 0;

var count = 9;

gl.drawArrays(primitiveType, offset, count);

webgl 着色器和GLSL

WebGL每次绘制需要两个着色器, 一个顶点着色器和一个片断着色器,每一个着色器都是一个方法。 一个顶点着色器和一个片断着色器链接在一起放入一个着色程序中(或者只叫程序)。 一个典型的WebGL应用会有多个着色程序。

这两个方法通常是在你的GPU上运行

顶点着色器

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

当对这些图元进行光栅化处理时需要使用片断着色器方法。 片断着色器的作用是计算出当前绘制图元中每个像素的颜色值。

片断着色器

一个片断着色器的工作是为当前光栅化的像素提供颜色值

代码语言:javascript复制
precision mediump float;

 

void main() {

   gl_FragColor = doMathToMakeAColor;

}

-------

var tex = gl.createTexture();

gl.bindTexture(gl.TEXTURE_2D, tex);

var level = 0;

var width = 2;

var height = 1;

var data = new Uint8Array([

   255, 0, 0, 255,   // 一个红色的像素

   0, 255, 0, 255,   // 一个绿色的像素

]);

gl.texImage2D(gl.TEXTURE_2D, level, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

着色器获取数据的4种方法

这些方法对所需的任何数据都需要发送到GPU

  • 1.属性(Attributes)和缓冲
  • 2.全局变量(Uniforms)
  • 3.纹理(Textures)
  • 4.可变量(Varyings)

着色器方式 属性(Attributes)和缓冲

代码语言:php [1-8|9-23]复制
// 属性可以用 float, vec2, vec3, vec4, mat2, mat3 和 mat4 数据类型

var string = `

  attribute vec4 a_position;

  void main() {

    gl_Position = a_position;

  }

`

// 创建缓冲

var buf = gl.createBuffer();

// 数据存入缓冲

gl.bindBuffer(gl.ARRAY_BUFFER, buf);

gl.bufferData(gl.ARRAY_BUFFER, someData, gl.STATIC_DRAW);

// 开启从缓冲中获取数据

gl.enableVertexAttribArray(positionLoc);

 

var numComponents = 3;  // (x, y, z)

var type = gl.FLOAT;    // 32位浮点数据

var normalize = false;  // 不标准化

var offset = 0;         // 从缓冲起始位置开始获取

var stride = 0;         // 到下一个数据跳多少位内存

                        // 0 = 使用当前的单位个数和单位长度 ( 3 * Float32Array.BYTES_PER_ELEMENT )

gl.vertexAttribPointer(positionLoc, numComponents, type, false, stride, offset);

gl.disableVertexAttribArray(positionLoc); // 关闭从缓冲中获取数据

着色器方式 全局变量(Uniforms)

全局变量在一次绘制过程中传递给着色器的值都一样,在下面的一个简单的例子中, 用全局变量给顶点着色器添加了一个偏移量

代码语言:php复制
// 着色器里

uniform vec2 u_someVec2[3];

 

// JavaScript 初始化时

var someVec2Loc = gl.getUniformLocation(someProgram, "u_someVec2");

 

// 渲染的时候

gl.uniform2fv(someVec2Loc, [1, 2, 3, 4, 5, 6]);  // 设置数组 u_someVec2

着色器方式 纹理(Textures)

代码语言:php [1-9|10-14]复制
var tex = gl.createTexture();

gl.bindTexture(gl.TEXTURE_2D, tex);

var level = 0;

var width = 2;

var height = 1;

var data = new Uint8Array([

   255, 0, 0, 255,   // 一个红色的像素

   0, 255, 0, 255,   // 一个绿色的像素

]);

gl.texImage2D(gl.TEXTURE_2D, level, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, data);

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

着色器方式 可变量(Varyings)

为了使用可变量,要在两个着色器中定义同名的可变量。 给顶点着色器中可变量设置的值,会作为参考值进行内插,在绘制像素时传给片断着色器的可变量

代码语言:php [1-6|7-13]复制
attribute vec4 a_position;

 

uniform vec4 u_offset;

 

varying vec4 v_positionWithOffset;

 

void main() {

  gl_Position = a_position   u_offset;

  v_positionWithOffset = a_position   u_offset;

}

GLSL

GLSL全称是 Graphics Library Shader Language (图形库着色器语言)

栅格化图形提供常用的计算功能,内建的数据类型例如vec2, vec3和 vec4分别代表两个值,三个值和四个值, 类似的还有mat2, mat3 和 mat4 分别代表 2x2, 3x3 和 4x4 矩阵

代码语言:javascript复制
vec4 a = vec4(1, 2, 3, 4);

vec4 b = a * 2.0;

// b 现在是 vec4(2, 4, 6, 8);

GLSL是一个强类型的语言

代码语言:javascript复制
float f = 1.0;      // 使用float

float f = float(1)  // 转换integer为float

vec4(v.rgb, 1) 不会因为 1 报错,因为 vec4 内部进行了转换类似 float(1)

查看规范

webgl 使用案例

案列:

沙发模型

洗衣机模

衣服模型

webgl使用

试用webgl

详细webgl

WebGL 需要掌握的知识点

  • 1.图像处理
  • 2.二维平移,旋转,缩放和矩阵运算
  • 3.三维(正射投影,透视投影, 相机)
  • 4.光照(方向光源,点光源,聚光灯)
  • 5.组织和重构
  • 6.几何
  • 7.纹理
  • 8.渲染到纹理
  • 9.阴影
  • 10.文字
  • 11.Optimization

0 人点赞