📅  最后修改于: 2023-12-03 15:38:28.282000             🧑  作者: Mango
在 3D 游戏或动画中,几何形状是非常重要的一部分。WebGL 和 p5.js 都提供了创建 3D 几何的库和功能。在本文中,我们将介绍如何在这两种库中创建 3D 几何。
WebGL 可以利用顶点数组创建几何形状。下面是一些示例代码,以创建基本的几何体。
// 创建 8 个顶点
const vertices = [
1, 1, 1,
-1, 1, 1,
-1, -1, 1,
1, -1, 1,
1, 1, -1,
-1, 1, -1,
-1, -1, -1,
1, -1, -1
];
// 创建 12 个三角形
const indices = [
0, 1, 2, 0, 2, 3,
4, 5, 6, 4, 6, 7,
0, 4, 7, 0, 7, 3,
1, 5, 6, 1, 6, 2,
0, 4, 5, 0, 5, 1,
3, 2, 6, 3, 6, 7
];
// 创建缓冲区
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
// 创建 360 个顶点
const vertices = [0, 0, 0];
let angle = 0;
for (let i = 0; i < 360; ++i) {
vertices.push(Math.cos(angle), 0, Math.sin(angle));
vertices.push(Math.cos(angle), 1, Math.sin(angle));
angle += Math.PI / 180;
}
vertices.push(0, 0, 0);
vertices.push(0, 1, 0);
// 创建 720 个三角形
const indices = [];
for (let i = 1; i < 361; ++i) {
indices.push(0, i, i + 1);
indices.push(361 + i, 361 + i + 1, 722);
indices.push(i, i + 1, 361 + i + 1);
indices.push(361 + i + 1, 361 + i, i + 1);
}
// 创建缓冲区
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
// 创建 2452 个顶点(每 10 度一个顶点)
const vertices = [];
for (let i = 0; i < 18; ++i) {
const latitude = (i / 18) * Math.PI;
for (let j = 0; j < 36; ++j) {
const longitude = (j / 36) * (Math.PI * 2);
vertices.push(
Math.sin(latitude) * Math.cos(longitude),
Math.cos(latitude),
Math.sin(latitude) * Math.sin(longitude)
);
}
}
vertices.push(0, 1, 0); // 顶部顶点
vertices.push(0, -1, 0); // 底部顶点
// 创建 4320 个三角形
const indices = [];
for (let i = 0; i < 17; ++i) {
for (let j = 0; j < 36; ++j) {
const topLeft = i * 36 + j;
const topRight = i * 36 + (j + 1) % 36;
const bottomLeft = (i + 1) * 36 + j;
const bottomRight = (i + 1) * 36 + (j + 1) % 36;
indices.push(topLeft, bottomLeft, topRight);
indices.push(bottomRight, topRight, bottomLeft);
}
}
for (let i = 0; i < 36; ++i) {
indices.push(i, (i + 1) % 36, 1080);
indices.push(1081, 1800 + i, 1800 + (i + 1) % 36);
}
// 创建缓冲区
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
const indexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, indexBuffer);
gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(indices), gl.STATIC_DRAW);
在 WebGL 中,变换是通过修改顶点坐标来实现的。以下代码将对物体进行平移、旋转和缩放。
// 平移
const translationMatrix = [
1, 0, 0, x,
0, 1, 0, y,
0, 0, 1, z,
0, 0, 0, 1
];
// 旋转
const rotationXMatrix = [
1, 0, 0, 0,
0, cos(theta), -sin(theta), 0,
0, sin(theta), cos(theta), 0,
0, 0, 0, 1
];
const rotationYMatrix = [
cos(theta), 0, sin(theta), 0,
0, 1, 0, 0,
-sin(theta), 0, cos(theta), 0,
0, 0, 0, 1
];
const rotationZMatrix = [
cos(theta), -sin(theta), 0, 0,
sin(theta), cos(theta), 0, 0,
0, 0, 1, 0,
0, 0, 0, 1
];
// 缩放
const scaleMatrix = [
x, 0, 0, 0,
0, y, 0, 0,
0, 0, z, 0,
0, 0, 0, 1
];
WebGL 使用着色器来对几何体进行着色。以下代码是一个简单的着色器,用于使用颜色渲染几何体。
const VSHADER_SOURCE = `
attribute vec4 a_Position;
attribute vec4 a_Color;
uniform mat4 u_ModelMatrix;
varying vec4 v_Color;
void main() {
gl_Position = u_ModelMatrix * a_Position;
v_Color = a_Color;
}
`;
const FSHADER_SOURCE = `
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}
`;
在 p5.js 中,可以使用 p5.js 的内置函数来创建基本的几何体。以下是一些示例代码。
const size = 100;
const cube = createBox(size, size, size);
const radius = 50;
const height = 100;
const cylinder = createCylinder(radius, height);
const radius = 50;
const sphere = createSphere(radius);
在 p5.js 中,可以使用 p5.js 的内置函数来进行变换。以下是一些示例代码。
// 平移
translate(x, y, z);
// 旋转
rotateX(theta);
rotateY(theta);
rotateZ(theta);
// 缩放
scale(x, y, z);
在 p5.js 中,可以使用内置的着色器来对几何体进行着色。以下是一个简单的着色器示例。
const vert = `
attribute vec4 a_Position;
attribute vec4 a_Color;
uniform mat4 u_ModelMatrix;
varying vec4 v_Color;
void main() {
gl_Position = u_ModelMatrix * a_Position;
v_Color = a_Color;
}
`;
const frag = `
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}
`;
const shader = createShader(vert, frag);
在本文中,我们介绍了如何在 WebGL 和 p5.js 中创建基本的 3D 几何体,并演示了如何进行基本的变换和着色。这只是 3D 游戏和动画编程的入门,但是掌握这些基础知识是非常重要的。