闲聊js17: 动画、数学与碰撞检测3(介绍一个支持simd,消除装箱拆箱的js数学库)

本篇目的:

  • gl-matrix库介绍
  • GPU为什么这么快
  • js新增的基本数据类型数组
  • 简单了解simd
  • 解释gl-matrix中各个数学类的用途以及2d中需要使用哪些类

gl-matrix简介:

  • gl-matrix github

  • gl-matrix官网文档

  • 介绍:
    Javascript has evolved into a language capable of handling realtime 3D graphics, via WebGL, and computationally intensive tasks such as physics simulations. These types of applications demand high performance vector and matrix math, which is something that Javascript doesn't provide by default. glMatrix to the rescue!

    glMatrix is designed to perform vector and matrix operations stupidly fast! By hand-tuning each function for maximum performance and encouraging efficient usage patterns through API conventions, glMatrix will help you get the most out of your browsers Javascript engine.

  • 从名称gl开头,就知道gl-matrix支持的是opengl风格的矩阵表示,这个以后在3D时候在讲吧。目前,了解一下就可以了,或者参考我写的Unity3D数学库的几个关键点这篇文章吧,不过也不详细,只是我对unity3d系统的数学库的总结。
    当你使用一个新的游戏引擎的时候,第一件事情就是了解坐标系,及数学系统是如何表示的。

  • 看一下gl-matrix中common.js源码:

var glMatrix = {};

// Configuration Constants
glMatrix.EPSILON = 0.000001;
glMatrix.ARRAY_TYPE = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
glMatrix.RANDOM = Math.random;
glMatrix.ENABLE_SIMD = false;

// Capability detection
glMatrix.SIMD_AVAILABLE = (glMatrix.ARRAY_TYPE === this.Float32Array) && ('SIMD' in this);
glMatrix.USE_SIMD = glMatrix.ENABLE_SIMD && glMatrix.SIMD_AVAILABLE;

如果js引擎支持内置对象Float32Array的话,则使用Float32Array,否则,使用Array对象

这是为了避免装箱拆箱(在2d 3d中,顶点变换是极其多的,可能会上万顶点数据进行矩阵变换,上万次的内存分配,复制,析构,好可怕!)

关于基本数据类型的装箱拆箱,可以参考我写的闲聊c/c++: 再谈内存(c/c++,java,c#,js,objc中的大小端以及装箱拆箱和统一类型系统)

关于SIMD,目前基本没有浏览器支持,属于实验性质的js库。

为什么GPU速度这么快:

  1. 是因为其流水线设计是专门针对3D变换,像素操作等功能,可以进行高度优化。而cpu必须要通用性,其流水线设计无法像GPU那样有针对性

  2. simd(cpu也支持,需要16byte对齐,高效利用cpu缓存)。整个GPU操作的数据类型,你会发现只有浮点数,而且都可以看成128bit数据(324):
    矢量 vector [x,y,z,w]
    四元数 quaternion [x,y,z,q]
    RGBA [r,g,b,a]
    plane [a,b,c,d]
    matrix 3行4列,相当于3个vector4
    GPU操作的数据类型都是128位对齐的浮点数。
    SIMD就是
    单指令多数据流*,一个add指令,将x,y,z,w同时做加法(一个add指令,同时做四次加法运算),而没有simd时候,必须x+x1,y+y1,z+z1,w+w1,简单形象理解就是如此而已!其实GPU还有很多重要的指标,例如位宽之类的,寄存器数量.....,以后我会专门写一片关于GPU以及高到18级以上的流水线相关文章,来介绍GPU编程方面的基础理论知识

  3. GPU的输入是顶点数据(位置,纹理坐标,输入颜色,.....,gl中称为vertex attributes,表示的是矢量信息),经过漫长的变换流水线,输出为RBGA颜色值(图像)。输出的目标可以是帧缓存(显示到电脑屏幕),也可以是纹理(渲染到纹理,然后再给纹理做各种特效,例如模糊,高光....等数字图像处理,视频也可以输出到纹理,进行播放)。

  4. 目前的超级计算机很多都是使用GPU集群进行计算,使用的是GPGPU(General Purpose GPU),原理和渲染流水线是一样的,将输入数据以顶点或像素方式表示,经过计算,输出到纹理中,然后从纹理读取计算后的结果。充分利用GPU强大的计算能力,实现通用计算。目前opencl标准就是该目的(opencv/opencl/opengl/openal这些都是很强大的库,搞图形图像音频GPU通用计算,还是需要了解或掌握的.而搞游戏引擎开发,那一定要深入了解。) 现在知道挖矿为什么要用顶级的GPU了吧。

  5. simd在cpu中也是长久的存在,intel 从mmx(1997年)到sse5,持续对simd进行支持(加速内存memcpy,图像处理,3D数学计算,音频视频编码解码.....,很多指令有专门用途)。各个平台,例如amd,arm都有对simd提供支持,具体查文档吧!

  6. 测试了一下,目前所有浏览器还没支持simd功能

gl-matrix中的类的作用:

  • mat2.js 表示2D旋转或缩放矩阵(无平移效果)
  • mat2d.js 表示2D仿射矩阵
  • mat3,js 表示3D旋转或缩放矩阵(无平移效果)
  • mat4.js 通用表示,支持仿射变换,投影变换,view摄像机矩阵等等
  • quat.js 四元数,表示物体旋转或朝向
  • vec2.js 2维矢量
  • vec3.js 3维矢量
  • vec4.js 4维矢量(齐次坐标)可以兼容表示plane(平面)数据,依赖你的操作

对于我们的2D引擎来说,只需要vec2.js 和 mat2d.js就能解决数学相关问题,mat2.js基本没啥用。其他的几个类用于3D操作。

下一篇,我们就来了解gl-matrix中的vec2.js

你可能感兴趣的:(闲聊js17: 动画、数学与碰撞检测3(介绍一个支持simd,消除装箱拆箱的js数学库))