大家好我是创意行业中的前端prupru。
最近在刷这本经典的《WebGL编程指南》给自己打基础,作者是日本东京大学工程系的Kouichi Matsuda博士和英国兰卡西特大学的Rodger Lea博士。
写得好好哦!非常适合初学者(比如我)。WebGL因为牵扯到GLSL ES的语言,对写惯了Javascript的小能手来说比较冗长。作者擅长把复杂的概念先包裹起来,再一步一步地吐露知识点,以此保证对初学者而言信息量不会过载。然而瞄了一眼豆瓣书评里有很多人恰恰很多人在批评这种做法……
但是我安利它!学习不怕慢,就怕太难劝退。
面向读者:初学者。学习目标:能够在Webgl中画点、线、三角形和简单图形,能够使用简单的颜色和图片纹理,三维方面能够在绘制图形的基础上,理解空间视图模型矩阵,控制模型的变换、视图变换、可视空间的控制、光照和阴影。
配套官网 sites.google.com/site/webglb…
怕自己忘先整理了第1~3章的思维导图,即在2D层面上画点、线和三角形的内容。
我按照自己的理解而不是按照书的章节进行了梳理。
如有理解错误的地方还请指教,谢谢!
# 《WebGL编程指南》1~3章
WebGL基本概念和API
## 概念
### WebGL
- 在网页中绘制三维图像,操控硬件的技术,由计算机图形语言OpenGL ES衍生而来。
运行WebGL包括1个HTML5的canvas元素,Javascript主程序的控制和WebGL程序的内部运行
- HTML5
-
<canvas width="400" height="400">$$请使用支持“canvas”的浏览器</canvas>
- Javascript见右边
- WebGL程序见右边
### 顶点着色器
- 描述图形顶点位置和大小的程序,GLSL ES语言
### 片元着色器
- 进行逐片元处理过程。片元是可以理解为图形像素,GLSL ES语言
### 坐标系统
- 默认为右手坐标系,x轴正方向友,y轴正方向上,z轴正方向朝屏幕外,范围都是(-1, 1),边缘即canvas元素的边缘
### 存储限定符
- 从Javascript向shader传输数据的变量
- attribute变量:传输与顶点相关的数据(随顶点变化而变化的数据)
- uniform变量:传输与顶点无关的不变的数据
- varying变量
### Javascript类型化数组
- int8Array
- Float32Array
- ...
## Javascript
### 编写顶点着色器Shader代码
var VSHADER_SOURCE = ...
### 编写片元着色器Shader代码
var FSHADER_SOURCE = ...
### 初始化WebGL Program
- 获取元素
- var canvas = document.querySelector('canvas');
- 获取iWebGL绘图上下文
- var gl = canvas.getContext('webgl')
### 初始化Shader
- 1.创建着色器对象
- var shader = gl.createShader(gl.VERTEX_SHADER / gl.FRAGMENT_SHADER)
- 2.向着色器对象中填充着色器程序的源代码
- gl.shaderSource(shader, source)
- 3.编译着色器
- gl.compileShader(shader)
- 4.创建程序对象
- var program = gl.createProgram()
- 5.为程序分配着色器
- gl.attachShader(program, shader)
- 6.连接程序对象
- gl.linkProgram(program)
- 7.使用程序对象
- gl.useProgram(program)
### 从Javascript向着色器传输单个数据
- 向attribute变量传输数据
- 向WebGL请求attribute变量的储存位置
(in Javascript)
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
- 向a_Position变量赋值
(in Javascript)
gl.vertexAttrib3f(a_Position, 0, 0, 0);
- 向uniform变量传输数据
- 向WebGL请求uniform变量的储存位置
(in Javascript)
var u_FragColor = gl.getUniformLocation(gl.program, 'u_FragColor');
- 向u_FragColor变量赋值
(in Javascript)
gl.uniform4f(u_FragColor, 0, 0, 0, 0);
### 从Javascript向着色器传输多个数据
- var vertices = new Float32Array([...]);
- 1.创建缓冲区对象
- var buffer = gl.createBuffer()
- 2.绑定缓冲区对象
- gl.binderBuffer(gl.ARRAY_BUFFER/..., buffer)
- 3.将数据写入缓冲区对象
- gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW/...)
- 4.将缓冲区对象分配给一个attribute变量
- gl.vertexAttribPointer(a_Position, size, gl.FLOAT, false, stride, offset)
- 5.开启attribute变量
- gl.enableVertexAttribArray(a_Position)
### 设置背景色
- gl.clearColor(r,g,b,a)
### 清空
- gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT)
### 绘制
- gl.drawArrays(mode, first, count)
- mode: gl.POINTS, gl.LINES, gl.LINE_STRIP,
gl.TRIANGLES, gl.TRIANGLES_STRIP
## 顶点着色器
Vertex Shader
### var VSHADER_SOURCE = '
// 声明attribute类型的变量 a_Position
attribute vec4 a_Position;
void main() {
// 将attribute变量赋值给gl_Position变量
gl_Position = a_Position;
gl_PointSize = 10.0;
}';
### Subtopic 2
## 片元着色器
Fragment Shader
### var FSHADER_SOURCE = '
// 声明uniform变量
uniform vec4 u_FragColor;
void main() {
gl_FragCoor = u_FragColor;
}';
## 在着色器代码中声明变量
<存储限定符> <类型> <变量名>
以attribute变量类型为例
attribute vec4 a_Position;