3D基础内容包括以下几个方面:
以上这些知识点是3D基础内容中比较重要的部分,如果想要深入学习3D相关的知识,还需要进一步了解数学、物理和计算机图形学等相关学科。
在3D基础中,视点、目标点和上方向是非常重要的概念,它们用于确定3D场景的视角和方向。
这些概念通常都是以向量的形式来表示的,视点和目标点可以表示为三维坐标系中的两个点,而上方向则表示为一个向量。在计算机图形学中,这些概念通常用于计算观察矩阵和投影矩阵,从而实现3D场景的渲染和动画效果。
3D基础的观察平面是指在三维坐标系中,我们所观察的物体在一个平面上显示的方式。这个平面通常被称为投影平面或视口(Viewport)。视口是一个矩形区域,它定义了我们所能看到的区域,并将三维场景中的物体映射到二维平面上。
在3D计算机图形学中,观察平面是指我们选择的一个视角,通过这个视角观察场景,并将其映射到视口上。观察平面通常与视口平面平行,因此将视口平面定义为观察平面。
不同的观察平面会导致对象的不同投影效果,例如平行投影和透视投影。平行投影是指在观察平面上,物体投影呈现为等比例的二维图形。而透视投影则是模仿人眼观察物体时的效果,使得远离观察平面的物体看起来比近处的物体更小。
因此,在进行3D图形的渲染时,我们需要选择合适的观察平面以及投影方式,以最大程度地展现出所需效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>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>
// 视图矩阵获取
function getViewMatrix(eyex, eyey, eyez, lookAtx, lookAty, lookAtz, upx, upy, upz) {
// 视点
const eye = new Float32Array([eyex, eyey, eyez])
// 目标点
const lookAt = new Float32Array([lookAtx, lookAty, lookAtz])
// 上方向
const up = new Float32Array([upx, upy, upz])
// 确定z轴
const z = minus(eye, lookAt);
normalized(z);
normalized(up);
// 确定x轴
const x = cross(z, up);
normalized(x);
// 确定y轴
const y = cross(x, z);
return new Float32Array([
x[0], y[0], z[0], 0,
x[1], y[1], z[1], 0,
x[2], y[2], z[2], 0,
-dot(x,eye),-dot(y,eye),-dot(z,eye),1
])
}
const ctx = document.getElementById('canvas')
const gl = ctx.getContext('webgl')
// 创建着色器源码
const VERTEX_SHADER_SOURCE = `
attribute vec4 aPosition;
uniform mat4 mat;
void main() {
gl_Position = mat * aPosition;
gl_PointSize = 10.0;
}
`; // 顶点着色器
const FRAGMENT_SHADER_SOURCE = `
void main() {
gl_FragColor = vec4(1.0,0.0,0.0,1.0);
}
`; // 片元着色器
const program = initShader(gl, VERTEX_SHADER_SOURCE, FRAGMENT_SHADER_SOURCE)
const aPosition = gl.getAttribLocation(program, 'aPosition');
const mat = gl.getUniformLocation(program, 'mat');
const points = new Float32Array([
-0.5, -0.5,
0.5, -0.5,
0.0, 0.5,
])
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, points, gl.STATIC_DRAW);
gl.vertexAttribPointer(aPosition, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(aPosition)
let eyey = -0.1;
function animation() {
eyey += 0.01;
if (eyey > 1) {
eyey = -0.1;
}
const vm = getViewMatrix(0.0,eyey,0.2,0.0,0.0,0.0,0.0,0.6,0.0);
// const matrix = getTranslateMatrix(x, x);
// gl.vertexAttrib1f(aTranslate, x);
gl.uniformMatrix4fv(mat, false, vm);
gl.drawArrays(gl.TRIANGLES, 0, 3);
requestAnimationFrame(animation);
}
animation()
</script>
归一化函数是一种将数据缩放到特定范围内的函数,常常用于数据预处理和特征缩放中。通常,归一化函数将原始数据映射到0到1之间的范围内,使得数据具有相同的尺度和范围,以便更好地进行比较和分析。
常见的归一化函数有最小-最大缩放法(Min-Max Scaling)、Z-score归一化法、小数定标规范化法等。其中,最小-最大缩放法是将原始数据中的最小值缩放到0,最大值缩放到1,其他值按比例缩放到0和1之间。Z-score归一化法是将原始数据的均值缩放到0,标准差缩放到1,使得数据分布近似于标准正态分布。小数定标规范化法是将原始数据除以某个基数的幂次方,使得缩放后的数据的最大绝对值不超过1。
归一化函数的具体选择取决于数据特点和应用需求。
在WebGL中,归一化函数的作用是将给定的坐标或向量转换为标准化设备坐标系中的坐标或向量。标准化设备坐标系是一个正方形区域,其范围从(-1, -1, -1)到(1, 1, 1),其中x、y和z坐标都在-1到1之间。归一化函数将给定的坐标或向量除以其长度或某个常数,以保证其值在标准化设备坐标系中的范围内。这是为了让WebGL引擎能够正确渲染三维场景,因为WebGL引擎只能处理在标准化设备坐标系中的坐标或向量。
// 归一化函数
function normalized(arr) {
let sum = 0;
for (let i = 0; i < arr.length; i++) {
sum += arr[i] * arr[i]
}
const middle = Math.sqrt(sum);
for (let i = 0; i < arr.length; i++) {
arr[i] = arr[i] / middle;
}
}
叉积是向量运算中的一种,表示两个向量相乘的结果是一个垂直于这两个向量的向量。具体来说,如果有两个向量
和
,则它们的叉积
的结果为:
的方向垂直于
和
所在的平面;
的模长等于以
和
所在平面为底面的平行四边形的面积;
、
和
满足右手定则。
因此,叉积的作用有:
、
、
分别表示笛卡尔坐标系的三个方向,将
和
写成分别以
、
、
为基的线性组合,即
,
,然后按照叉积的公式计算即可。
和
所在平面为底面的平行四边形的面积,因此可以利用叉积来计算平行四边形的面积。
和
,它们的方向已经确定了,因此它们的叉积
代表的向量也是确定的。这个向量可以被认为是旋转轴,而
和
的夹角
可以被认为是旋转的角度。在计算机图形学中,经常使用叉积来进行物体的旋转和变换。
WebGL中的叉积函数,即cross函数,可以用于计算两个三维向量的叉积。叉积是一个向量,其方向垂直于两个向量所在的平面,大小等于这两个向量所在平面的面积。在三维图形编程中,叉积函数的应用场景很多,例如:
// 叉积函数 获取法向量
function cross(a,b) {
return new Float32Array([
a[1] * b[2] - a[2] * b[1],
a[2] * b[0] - a[0] * b[2],
a[0] * b[1] - a[1] * b[0],
])
}
点积,又称内积或数量积,是数学中两个向量之间的一种运算,用符号“·”表示。具体地,设两个n维向量a和b,它们的点积定义为:
a·b = a1b1 + a2b2 + … + anbn
也就是将两个向量对应位置的元素相乘,并将乘积相加得到的一个标量。点积在向量和矩阵运算中具有重要作用。
点积有以下几个作用:
在WebGL中,点积函数用于计算两个向量的点积(也称为内积或数量积),其结果是一个标量值。点积函数可以用于许多不同的应用中,例如:
总之,点积函数在WebGL中具有广泛的应用,是计算向量间关系和位置的重要工具。
// 点积函数 获取投影长度
function dot(a, b) {
return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]
}
向量差是指两个向量相减得到的新向量。具体地,如果有向量A和向量B,则向量差C=A-B,表示从B指向A的向量。
向量差的作用包括:
在WebGL中,向量差函数可以计算两个向量之间的差值。这通常用于计算两个点之间的距离或计算一个向量的方向和另一个向量的反向。向量差函数也可以用于执行几何变换,例如将物体沿某个方向移动或旋转。在WebGL中,向量差函数通常是内置的,并使用GLSL编程语言的函数库进行实现。
// 向量差
function minus(a, b) {
return new Float32Array([
a[0] - b[0],
a[1] - b[1],
a[2] - b[2],
])
}