WebGL简介
WebGL是一种JavaScript API,用于在不使用外挂程式的情况下在任何相容的网页浏览器中呈现交互式2D和3D图形[3]。WebGL完全整合到浏览器的所有网页标准中,可将影像处理和效果的GPU加速使用方式当做网页Canvas的一部分。WebGL元素可以加入其他HTML元素之中并与网页或网页背景的其他部分混合[4]。WebGL程序由JavaScript编写的控制代码和OpenGL Shading Language(GLSL)编写的著色器代码组成,该语言类似于C或C++,并在电脑的图形处理器(GPU)上执行。WebGL由非营利Khronos Group设计和维护[5]。
兼容性:(截止2023年6月)
GLSL
GLSL - OpenGL Shading Language 也称作 GLslang,是一个以C语言为基础的高阶着色语言。它是由 OpenGL ARB 所建立,提供开发者对绘图管线更多的直接控制,而无需使用汇编语言或硬件规格语言。
想要使用WebGL作图就必须要使用到着色器(shader)。着色器包括:
- 顶点着色器(Vertex shader)用来描述顶点的特征(位置、颜色、大小等),顶点指的就是空间中的某一个点。
- 片元着色器(Fragment shader)处理每一个片元,片元可以理解成像素点。
比如说我们想画一个三角形首先要知道三角形的三个点在哪,这就需要我们通过顶点着色器来描述点的位置,然后如果要把这个三角形画出来就需要填充颜色,三角形上每个像素点需要什么颜色就可以使用片元着色器来决定。
所以,我们一般利用JavaScript中创建字符串的方式创建GLSL字符串:用串联的方式(concatenating)(用得最多), 用AJAX下载,用多行模板数据。
gl_FragColor是一个片段着色器主要设置的变量、gl_Position 是一个顶点着色器主要设置的变量
// 顶点着色器glsl代码
const vsSource = `
attribute vec4 aVertexPosition;
attribute vec4 aVertexColor;
varying lowp vec4 vColor;
void main() {
gl_Position = aVertexPosition;
vColor = aVertexColor;
}
`;
// 片段着色器glsl代码
const fsSource = `
varying lowp vec4 vColor;
void main() {
gl_FragColor = vColor;
}
`;
或者在这个例子里,我们可以将它们放在非JavaScript类型的标签中。
<script id="vertex-shader-2d" type="notjs">
//xxxxxx
</script>
然后,我们通过对GLSL数据的上传,然后编译成。顶点/片元 着色器。
创建着色器需要走三步:
- createShader: 创建着色器对象
- shaderSource: 提供数据源
- compileShader: 编译 -> 生成着色器
// 创建着色器,gl为上下文,type指明是顶点着色器还是片段着色器,source即为源码
function createShader(gl, type, source) {
const shader = gl.createShader(type); // 创建着色器对象
gl.shaderSource(shader, source); // 提供数据源
gl.compileShader(shader); //编译 -> 生成着色器
var success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
if (success) {
return shader;
} else {
//一些处理
}
return shader;
}
然后把着色器链接(link)到着色程序中
//初始化着色程序
export function initShaderProgram(gl, vsSource, fsSource) {
const vshader = createShader(gl, gl.VERTEX_SHADER, vsSource);
const fshader = createShader(gl, gl.FRAGMENT_SHADER, fsSource);
const shaderProgram = gl.createProgram(); // 创建着色器程序
gl.attachShader(shaderProgram, vshader); // 链接着色器到对应的着色器程序中
gl.attachShader(shaderProgram, fshader);
gl.linkProgram(shaderProgram); // 关联着色器程序到整个绘制对象中
var success = gl.getProgramParameter(shaderProgram, gl.LINK_STATUS);
if (success) {
return shaderProgram;
} else {
//一些处理
}
}
Basic 语法
(1)变量类型
属性(Attributes)和缓冲
缓冲是发送到GPU的一些二进制数据序列,通常情况下缓冲数据包括位置,法向量,纹理坐标,顶点颜色值等。 你可以存储任何数据。我们可以理解为和threejs 的 attribute 类似
全局变量(Uniforms)
全局变量在着色程序运行前赋值,在运行过程中全局有效。
纹理(Textures)
纹理是一个数据序列,可以在着色程序运行中随意读取其中的数据。 大多数情况存放的是图像数据,但是纹理仅仅是数据序列, 你也可以随意存放除了颜色数据以外的其它数据。
可变量(Varyings)
可变量是一种顶点着色器给片段着色器传值的方式,依照渲染的图元是点, 线还是三角形,顶点着色器中设置的可变量会在片段着色器运行中获取不同的插值。
(2)基本类型
void空类型,即不返回任何值
bool布尔类型 true,false
int带符号的整数 signed integer
float带符号的浮点数 floating scalar
vec2, vec3, vec4n维浮点数向量 n-component floating point vector
bvec2, bvec3, bvec4n维布尔向量 Boolean vector
ivec2, ivec3, ivec4n维整数向量 signed integer vector
mat2, mat3, mat42x2, 3x3, 4x4 浮点数矩阵 float matrix
sampler2D2D纹理 a 2D texture
samplerCube盒纹理 cube mapped texture
精度限定符
精度范围
- 浮点数范围
- highp (-2的62次方, 2的62次方);
- mediump (-2的14次方, 2的14次方);
- lowp (-2,2);
- 整数范围
- highp (-2的16次方, 2的16次方);
- mediump (-2的10次方, 2的10次方);
- lowp (-2的8次方, 2的8次方);
- 浮点数范围
指定默认精度
precision
顶点着色器预定义,预定义即为默认值
precision highp float; // 浮点数高精度 precision highp int; // 整型高精度 precision lowp sampler2D; precision lowp samplerCube;
片段着色器预定义
precision mediump int; // 整型中精度 precision lowp sampler2D; precision lowp samplerCube;
兼容性
var gl = canvas.getContext("webgl");
if (!gl) {
// 你不能使用WebGL!
...