文章目录
Canvas是什么
canvas是透明的,2d坐标系统的x轴(正方向朝右)
,y轴(正方向朝下)
。
<canvas id="canvas2d" class="m-auto" width="720" height="100"> </canvas>
<script>
var canvas = document.getElementById("canvas2d") as HTMLCanvasElement;
if (!canvas) {
console.log("Failed to retrieve the <canvas> element");
} else {
// 获取canvas上下文
var ctx = canvas.getContext("2d");
if (ctx) {
// 设置填充颜色
ctx.fillStyle = "oklch(0.769 0.188 70.08)";
// 绘制矩形
ctx.fillRect(0, 0, 720, 100);
}
}
</script>
绘制第一个3d图形
绘制三维图形与二维类似,也遵循类似的步骤,获取canvas元素、获取绘图上下文、开始绘图。
<canvas id="canvas3d" class="m-auto" width="720" height="400"> </canvas>
<script type="module">
function canvas3D() {
var canvas = document.getElementById("canvas3d");
if (!canvas) {
return console.log("Failed to retrieve the <canvas> element");
}
console.dir(canvas);
// 获取webgl绘图上下文
var gl = getWebGLContext(canvas);
if (!gl) {
console.log("Failed to get the redering context for WebGL");
return;
}
// 指定清空canvas的颜色
gl.clearColor(0.0, 0.5, 0.5, 1.0);
// 清空canvas
gl.clear(gl.COLOR_BUFFER_BIT);
}
canvas3D();
</script>
gl.clearColor(red, green, blue, alpha)
,指定绘图区域的背景色。
定义 | 名称 | 解释 |
---|---|---|
参数 | red | 指定红色值(从0.0到1.0) |
green | 指定绿色值(从0.0到1.0) | |
blue | 指定蓝色值(从0.0到1.0) | |
alpha | 指定透明度(从0.0到1.0) |
如果任何一个分量小于0.0或者大于1.0,那么就会分别截断为0.0或1.0
一旦指定了背景色之后,背景色就会驻存在WebGL系统(WebGL System)中,在下一次调用gl.clearColor()方法前不会改变。如果将来什么时候你还想用同一个颜色再清空一次绘图区,没必要再指定一次背景色,你可以调用gl.clear()函数,用之前指定的背景色清空(即用背景色填充,擦除已经绘制的内容)绘图区域。
清空Canvas
- gl.COLOR_BUFFER_BIT -> 指定颜色缓冲区
- gl.DEPTH_BUFFER_BIT -> 指定深度缓冲区
- gl.STENCIL_BUFFER_BIT -> 指定模板缓冲区
gl.clearColor(gl.COLOR_BUFFER_BIT)
清空颜色缓冲区。因为webgl的gl.clearColor
继承opengl,基于多基本缓冲区模型,gl.COLOR_BUFFER_BIT
代表的是颜色缓冲区。webgl还有深度缓冲区和模板缓冲区。
绘制一个点
const VSHADER_SOURCE = `
void main() {
gl_Position = vec4(0.0, 0.0, 0.0, 1.0); // 设置坐标
gl_PointSize = 5.0; // 设置点的大小
}
`;
const FSHADER_SOURCE = `
void main() {
gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 设置点的颜色
}
`;
let canvas = document.getElementById('drawPoint');
// @ts-ignore
var gl = window.getWebGLContext(canvas);
if (!gl) {
console.log('Failed to gwt the rendering context for WebGL.');
return;
}
if (!initShaders(gl, VSHADER_SOURCE, FSHADER_SOURCE)) {
console.log('Failed to initialize shaders.');
return;
}
gl.clearColor(0.0, 0.0, 0.0, 1.0); // 设置清屏颜色为黑色
gl.clear(gl.COLOR_BUFFER_BIT); // 清除颜色缓冲区
gl.drawArrays(gl.POINTS, 0, 1); // 设置绘制模式为点,顶点索引从0开始,共绘制1个点
顶点着色器
顶点着色器
控制点的位置和大小,它用来描述顶点特性(如位置,颜色等)的程序。顶点是指二维和三维空间的一个点,比如二维或三维图形的端点或交点。
- 内置变量
- vec4 gl_Position -> 表示顶点位置(该属性必须被赋值)
- float gl_PointSize -> 表示顶点尺寸(默认1.0)
片元着色器
进行逐片元处理如光照的程序。片元
是一个图形学术语,可理解为像素(图像的单元,包括这个像素的位置,颜色和其他信息)。
- 内置变量
- vec4 gl_FragColor -> 指定片元的颜色(RGBA格式)
绘制
gl.drawArrays可用于绘制各种图形,简单介绍如下
gl.drawArrays(mode,frst,count)
执行顶点着色器,按照 mode 参数指定的方式绘制图形。
参数 | 说明 | 类型 |
---|---|---|
mode | 指定绘制的方式,可接收以下常量符号: gl.POINTS ,gl.LINES ,gl.LINE_STRIP ,gl.LINE_LOOP ,gl.TRIANGLES ,gl.TRIANGLE_STRIP ,gl.TRIANGLE_FAN | 枚举 |
first | 指定从哪个顶点开始绘制 | 整型数 |
count | 指定绘制需要用到多少个顶点 | 整型数 |
当程序调用g1.drawArrays()时,顶点着色器将被执行count次,每次处理一个顶点。
WebGL坐标系统
<canvas>
的中心点: (0.0,0.0,0.0)<canvas>
的上边缘和下边缘: (-1.0,0.0,0.0)和(1.0,0.0,0.0)<canvas>
的左边缘和右边缘: (0.0,-1.0,0.0)和(0.0,1.0,0.0)
attribute变量和uniform变量
attribute
变量传输的是那些与顶点相关的数据,而uniform
变量传输的是那些对于所有顶点都相同(或与顶点无关)的数据。
attribute
变量是一种 GLSL ES变量,被用来从外部向顶点着色器内传输数据,只有顶点着色器能使用它。为了使用 attribute 变量,需要包含以下步骤
- 在顶点着色器中,声明attribute变量;
- 将attribute 变量赋值给gl_Position变量;
- 向 attribute 变量传输数据。
使用js设置attribute变量画一个点
这里随意点击即可绘制一个点
const VSHADER_SOURCE = `
attribute vec4 a_Position;
void main() {
gl_Position = a_Position; // 设置坐标
gl_PointSize = 10.0; // 设置点的大小
}
`;
// ... 中间代码与上一版相同
// gl.getAttribLocation函数用于获取a_Position变量指定的attribute变量的存储地址
// 简单理解:让gl帮忙创建一个变量
var a_Position = gl.getAttribLocation(gl.program, 'a_Position');
// ...
// 将数据(0.0, 0.0, 0.0)传给由a_Position参数指定的attribute 变量。
// 简单理解:让gl帮忙给变量赋值
gl.vertexAttrib3f(a_Position, 0.0, 0.0, 0.0); // 设置顶点位置
gl.clearColor(0.0, 0.0, 0.0, 1.0); // 设置清屏颜色为黑色
gl.clear(gl.COLOR_BUFFER_BIT); // 清除颜色缓冲区
gl.drawArrays(gl.POINTS, 0, 1); // 设置绘制模式为点,顶点索引从0开始,共绘制1个点
attribute vec4 a_Position
,attribute
被称为存储限定符
attribute
变量都以a_前缀开始uniform
变量都以u_前缀开始 设置vec4
变量时,当省略分量时,默认为1.0
gl.vertexAttrib3f
和gl.vertexAttrib3fv
区别在于参数的接收,3f逐个接收三个参数,3fv接受一个长度为3的数组