webgl 系列
着色器语言
GLSL全称是 Graphics Library Shader Language (图形库着色器语言
)
GLSL 比较简单
。其专门用于编写着色器,舍弃了许多编程语言中复杂的东西,比如没有字符串,只有数字
。
Tip: webgl 1.0 绝大多数浏览器都支持,webgl 2.0 支持度差些。webgpu 旨在取代WebGL,浏览器兼容惨不忍睹。
准备
三角形的学习,我们很容易绘制如下矩形:
// 顶点着色器
const VSHADER_SOURCE = `
attribute vec4 a_Position;
void main( {
gl_Position = a_Position;
gl_PointSize = 10.0;
}
`
// 片元着色器
const FSHADER_SOURCE = `
void main( {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0;
}
`
function main( {
const canvas = document.getElementById('webgl';
const gl = canvas.getContext("webgl";
if (!gl {
console.log('Failed to get the rendering context for WebGL';
return;
}
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE {
console.log('Failed to intialize shaders.';
return;
}
gl.clearColor(0, 0, 0, 1;
gl.clear(gl.COLOR_BUFFER_BIT;
const vertices = {
data: new Float32Array([
-0.5, 0.5,
-0.5, -0.5,
0.5, -0.5,
0.5, 0.5
],
vertexNumber: 4,
count: 2,
}
initVertexBuffers(gl, vertices
gl.drawArrays(gl.TRIANGLE_FAN, 0, vertices.vertexNumber;
}
function initVertexBuffers(gl, {data, count} {
const vertexBuffer = gl.createBuffer(;
if (!vertexBuffer {
console.log('创建缓冲区对象失败';
return -1;
}
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer;
gl.bufferData(gl.ARRAY_BUFFER, data, gl.STATIC_DRAW;
const a_Position = gl.getAttribLocation(gl.program, 'a_Position';
if (a_Position < 0 {
console.log('Failed to get the storage location of a_Position';
return -1;
}
gl.vertexAttribPointer(a_Position, count, gl.FLOAT, false, 0, 0;
gl.enableVertexAttribArray(a_Position;
}
将顶点着色器
和片元着色器
提取出单独的 js 文件。就像这样:
// demo\shader\fShader.js
const FSHADER_SOURCE = /* glsl */ `
void main( {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0;
}`
// demo\shader\vShader.js
const VSHADER_SOURCE = /* glsl */ `
attribute vec4 a_Position;
void main( {
gl_Position = a_Position;
gl_PointSize = 10.0;
}
`;
这里的 /* glsl */
用于 vscode 高亮 glsl。就像这样(左侧高亮):
高亮 glsl
Comment tagged templates(重启后仍未生效,后切换安装的版本,再次重启即可):
WebGL GLSL Editor,直接编写 .glsl
就能高亮:
基础
- 区分大小写
- 每个语句以一个分号结束
- 单行注释
//
、多行注释/* */
// 单行注释
/*
多行注释
*/
变量名
变量命名规则如下:
- 只能包含字母、数字、下划线
- 首字母不能是数字
- 不能是关键字和保留字
- 不能以
gl_
、webgl_
或_webgl_
开头,这部分已经被 OpengGL ES 保留了
Tip: 变量的命名就按照js的习惯来就好,如果有问题,浏览器会给出较好的错误提示。就像这样:
// 只能包含字母、数字、下划线 - ERROR: 0:15: '$' : invalid character
int a$ = 1;
// 首字母不能是数字 - ERROR: 0:11: '0aA0_' : invalid number
int 0aA0_ = 1;
// 不能是关键字 - ERROR: 0:19: 'for' : syntax error
int for = 1;
// 不能是保留字 - Illegal use of reserved word 非法使用保留字
int class = 1;
// 不能以 gl_、webgl_ 或 _webgl_ 开头 - ERROR: 0:24: 'gl_' : reserved built-in name 保留的内置名称
int gl_a = 1;
基本类型
不像 js 有 number、string、boolean、null、undefined、bigint、symbol 等 7 种基本类型,这里只有数字(int
、float
和布尔(bool
。
// 精度限定字。否则浏览器控制台报错:No precision specified for (float
precision mediump float;
int a = 1; // 整型
float b = 1.0; // 浮点
bool c = true; // 布尔类型
Tip: js 不区分整数和浮点数,其数字都是64位的双精度,类似 java 中的 double。而如果把整数赋值给 flat(float b = 1;
就会报错。
类型转换
由于基本类型就三种(int、float、bool),所以类型转化也较js简单多了,共 6 种。
-
int(bool
- 转整型。true 转 1,false 转 0 -
float(int
- 转浮点。(比如 1 转 1.0) -
float(bool
- 转浮点。true 转 1.0,false 转 0.0 -
bool(int
- 0 转 false,非 0 转 true -
bool(float
- 0 转 fa
int(float
- 转整型。删除浮点小数部分,转为整数(比如 3.14 转为 3)