内容简介:WebGL 实质上是一个光栅化引擎,根据你的代码绘制出点,线和三角形。WebGL 每次绘制需要两个着色器, 一个顶点着色器和一个片断着色器,每一个着色器都是一个方法。 一个顶点着色器和一个片断着色器链接在一起放入一个着色程序中(或者只叫程序)。一个典型的 WebGL 应用会有多个着色程序。对于二维变换使用 3x3 矩阵,可以快速的实现平移,旋转,缩放,单位化效果。
一、概念基础
WebGL 实质上是一个光栅化引擎,根据你的代码绘制出点,线和三角形。
- 成对方法:在 GPU 上运行的 WebGL 代码需要是成对的方法,每对方法中一个叫顶点着色器, 另一个叫片断着色器,用 GLSL 编码。每一对组合起来称作一个 program(着色程序)。
- 属性(Attributes)和缓冲:缓冲是发送到 GPU 的一些二进制数据序列,通常情况下缓冲数据包括位置,法向量,纹理坐标,顶点颜色值等。属性用来指明怎么从缓冲中获取所需数据并将它提供给顶点着色器。
- 全局变量(Uniforms):在着色程序运行前赋值,在运行过程中全局有效。
- 纹理(Textures):纹理是一个数据序列,可以在着色程序运行中随意读取其中的数据。
- 可变量(Varyings):是一种顶点着色器给片断着色器传值的方式。
WebGL 每次绘制需要两个着色器, 一个顶点着色器和一个片断着色器,每一个着色器都是一个方法。 一个顶点着色器和一个片断着色器链接在一起放入一个着色程序中(或者只叫程序)。一个典型的 WebGL 应用会有多个着色程序。
-
顶点着色器需要的数据,获取方式分三种:
- Attributes 属性 (从缓冲中获取的数据)
- Uniforms 全局变量 (在一次绘制中对所有顶点保持一致值)
- Textures 纹理 (从像素或纹理元素中获取的数据)
-
片段着色器所需的数据,获取方式分三种:
- Uniforms 全局变量 (values that stay the same for every pixel of a single draw call)
- Textures 纹理 (data from pixels/texels)
- Varyings 可变量 (data passed from the vertex shader and interpolated)
- GLSL 是门强类型语言,以下是一些用法枚举:
// vec2, vec3和 vec4分别代表两个值,三个值和四个值 vec4 a = vec4(1, 2, 3, 4); vec4 b = a * 2.0; // b 现在是 vec4(2, 4, 6, 8); // mat2, mat3 和 mat4 分别代表 2x2, 3x3 和 4x4 矩阵 mat4 a = ??? mat4 b = ??? mat4 c = a * b; vec4 v; // v.x 和 v.s 以及 v.r , v[0] 表达的是同一个分量。 // v.y 和 v.t 以及 v.g , v[1] 表达的是同一个分量。 // v.z 和 v.p 以及 v.b , v[2] 表达的是同一个分量。 // v.w 和 v.q 以及 v.a , v[3] 表达的是同一个分量。 v.yyyy // === vec4(v.y, v.y, v.y, v.y) v.bgra // === vec4(v.b, v.g, v.r, v.a) vec4(1) // === vec4(1, 1, 1, 1) // 支持矢量调制 // 如果 v1 和 v2 都是 vec4, f 是浮点型,以下两个变量等价 vec4 m = mix(v1, v2, f); vec4 m = vec4( mix(v1.x, v2.x, f), mix(v1.y, v2.y, f), mix(v1.z, v2.z, f), mix(v1.w, v2.w, f));
二、二维变换
对于二维变换使用 3x3 矩阵,可以快速的实现平移,旋转,缩放,单位化效果。
var m3 = {
translation: function(tx, ty) {
return [
1, 0, 0,
0, 1, 0,
tx, ty, 1,
];
},
rotation: function(angleInRadians) {
var c = Math.cos(angleInRadians);
var s = Math.sin(angleInRadians);
return [
c,-s, 0,
s, c, 0,
0, 0, 1,
];
},
scaling: function(sx, sy) {
return [
sx, 0, 0,
0, sy, 0,
0, 0, 1,
];
},
identity: function() {
return [
1, 0, 0,
0, 1, 0,
0, 0, 1,
];
},
};
关于如下一个矩阵计算,有两种解释方式:
projectionMat * translationMat * rotationMat * scaleMat * position
从右向左解释:首先将位置乘以缩放矩阵获得缩放后的位置,然后将缩放后的位置和旋转矩阵相乘得到缩放旋转位置,然后将缩放旋转位置和平移矩阵相乘得到缩放旋转平移位置,最后和投影矩阵相乘得到裁剪空间中的坐标。
从左往右解释:每一个矩阵改变的都是画布的坐标空间, 画布的起始空间是裁剪空间的范围(-1 到 +1),矩阵从左到右改变着画布所在的空间。
三、三维变换
- WebGL 中的三角形有正反面概念,通过下面代码可以开启不绘制背面三角形(顺时针方向)的特性。
gl.enable(gl.CULL_FACE);
- 深度缓冲(DEPTH BUFFER):WebGL 绘制一个着色像素之前会检查对应的深度像素, 如果对应的深度像素中的深度值小于当前像素的深度值,WebGL 就不会绘制新的颜色。 反之它会绘制片断着色器提供的新颜色并更新深度像素中的深度值。如下命令可以开启这个特性:
gl.enable(gl.DEPTH_TEST);
- 三维矩阵相比二维多一行一列,(x,y,z,w) 中 w 可以用于透视投影(近大远小)处理。
- 日常观察的物体都应是透视投影,而非正射投影。
四、动画与纹理
实现动画与 WebGL 并不直接相关,需要利用 JavaScript 随着时间改变一些值然后绘制。在此处请使用 requestAnimationFrame API.
-
GPU 在绘制时使用的是一个纹理贴图,它是一个逐渐缩小的图像集合, 每一个是前一个的四分之一大小(方法:双线性插值)。
gl.generateMipmap做的事情就是根据原始图像创建所有的缩小级别。使用generateMipmap时需注意纹理的维度必须是2的整数次幂。
由于纹理需要异步加载资源,所以在物体渲染上存在两种处理方式。
- 纹理图集:将多个图像通过一个纹理提供的方法,即将图像放在一个纹理中,然后利用纹理坐标映射不同的图像到每个面。
五、组织结构
一个 WebGL 应用推荐遵循的结构
-
初始化阶段
- 创建所有着色器和程序并寻找参数位置
- 创建缓冲并上传顶点数据
- 创建纹理并上传纹理数据
-
渲染阶段
- 清空并设置视图和其他全局状态(开启深度检测,剔除等等)
-
对于想要绘制的每个物体(此处可抽象复用)
-
调用
gl.useProgram使用需要的程序 -
设置物体的属性变量
-
为每个属性调用
gl.bindBuffer,gl.vertexAttribPointer,gl.enableVertexAttribArray
-
为每个属性调用
-
设置物体的全局变量
-
为每个全局变量调用
gl.uniformXXX -
调用
gl.activeTexture和gl.bindTexture设置纹理到纹理单元 -
调用
gl.drawArrays或gl.drawElements
-
为每个全局变量调用
-
调用
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
An Introduction to Genetic Algorithms
Melanie Mitchell / MIT Press / 1998-2-6 / USD 45.00
Genetic algorithms have been used in science and engineering as adaptive algorithms for solving practical problems and as computational models of natural evolutionary systems. This brief, accessible i......一起来看看 《An Introduction to Genetic Algorithms》 这本书的介绍吧!