一、WebGL3D基础知识
1.3D坐标系
webGL坐标系统,x沿水平方向从左到右,y垂直向上,z指向屏幕向外这些都是正方向
canvas坐标系统,z,x一样,但是y是向下的。
浏览器坐标系,x,是向左、y是向下的。
tip: 鼠标点击的是浏览器的坐标系统,要先转换为Canvas的坐标系统,也就是0点是不一致的。然后就是webGL的坐标要进行归一化。同时把原点切换到Canvas的中心。
2.网格,多边形,顶点
网格:就是有一个或多个多边形拼接而成的,网格只能确定形状不能确定色彩和明暗等
多边形:多指三角形和四边形
模型:也就是3D的网格的别名
顶点:就是定义多边形位置的3D空间位置,也就是x,y,z的一组值
3.材质,纹理,光源
这些属性都是用来描述网格外观,包括简单的色彩属性和复杂的反射,明暗etc
纹理映射(也就是通常说的纹理):就是使用一个或多个位图表示外观信息
材质:网格外观属性的统称
光源:光源可以是一个或多个,决定了场景被照亮的模式
4.变换,矩阵
要区别世界坐标系和视图坐标投影坐标和对象坐标转换的矩阵
矩阵都是4*4的
变换是通过矩阵来实现的,要区别左右?
不要傻傻的想for一个一个点来操作。
5.相机,透视,窗口,投影
相机 就是对应的观察点,决定了位置和方向,其实它一般是一个矩阵
透视 就是远小近大
视口 浏览器窗口和canvas元素决定的
其实所有的变换都是矩阵操作。
二、顶点法绘制立方体
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>立方体绘制</title>
<script src="../../lib/index.js"></script>
<style>
* {
margin: 0;
padding: 0;
}
canvas{
margin: 50px auto 0;
display: block;
background: yellow;
}
</style>
</head>
<body>
<canvas id="canvas" width="400" height="400">
此浏览器不支持canvas
</canvas>
</body>
</html>
<script>
const ctx = document.getElementById('canvas')
const gl = ctx.getContext('webgl')
// 创建着色器源码
const VERTEX_SHADER_SOURCE = `
attribute vec4 aPosition;
attribute vec4 aColor;
varying vec4 vColor;
uniform mat4 mat;
void main() {
gl_Position = mat * aPosition;
vColor = aColor;
}
`; // 顶点着色器
const FRAGMENT_SHADER_SOURCE = `
precision lowp float;
varying vec4 vColor;
void main() {
gl_FragColor = vColor;
}
`; // 片元着色器
const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
const aPosition = gl.getAttribLocation(program, 'aPosition');
const aColor = gl.getAttribLocation(program, 'aColor');
const mat = gl.getUniformLocation(program, 'mat');
// 顶点
const v0 = [1,1,1];
const v1 = [-1,1,1];
const v2 = [-1,-1,1];
const v3 = [1,-1,1];
const v4 = [1,-1,-1];
const v5 = [1,1,-1];
const v6 = [-1,1,-1];
const v7 = [-1,-1,-1];
const points = new Float32Array([
...v0,...v1,...v2, ...v0,...v2, ...v3, // 前
...v0,...v3,...v4, ...v0,...v4, ...v5, // 右
...v0,...v5,...v6, ...v0,...v6, ...v1, // 上面
...v1,...v6,...v7, ...v1,...v7, ...v2, // 左
...v7,...v4,...v3, ...v7,...v3, ...v2, // 底
...v4,...v7,...v6, ...v4,...v6, ...v5, // 后
])
const buffer = gl.createBuffer();
const BYTES = points.BYTES_PER_ELEMENT;
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
gl.vertexAttribPointer(aPosition, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aPosition)
const colorData = new Float32Array([
1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,
0,1,0,0,1,0,0,1,0,0,1,0,0</