原生几何体
Box(立方体)
js
const box = BABYLON.MeshBuilder.CreateBox("box", { size: 2, faceColors: [
BABYLON.Color3.Blue(),
BABYLON.Color3.Red(),
BABYLON.Color3.Green(),
BABYLON.Color3.Yellow(),
BABYLON.Color3.Purple(),
BABYLON.Color3.Orange()
] }, scene);Sphere(球体)
js
const sphere = BABYLON.MeshBuilder.CreateSphere("sphere", { diameter: 2, segments: 32 }, scene);Cylinder(圆柱体)
js
const cylinder = BABYLON.MeshBuilder.CreateCylinder("cylinder", { height: 3, diameterTop: 1, diameterBottom: 1, tessellation: 24, enclose: true }, scene);Plane(平面)
js
const plane = BABYLON.MeshBuilder.CreatePlane("plane", { size: 5, sideOrientation: BABYLON.Mesh.DOUBLESIDE }, scene);Torus(圆环体)
js
const torus = BABYLON.MeshBuilder.CreateTorus("torus", { radius: 2, tube: 0.5, tessellation: 32 }, scene);MeshBuilder
支持链式调用,可以在一个语句中设置多个属性
js
const box = BABYLON.MeshBuilder.CreateBox("box", {
size: 2,
faceColors: [
BABYLON.Color3.Blue(),
BABYLON.Color3.Red(),
BABYLON.Color3.Green(),
BABYLON.Color3.Yellow(),
BABYLON.Color3.Purple(),
BABYLON.Color3.Orange()
],
position: new BABYLON.Vector3(0, 1, 0)
}, scene);参数化创建 创建一个带有不同尺寸的圆柱体
js
const cylinder = BABYLON.MeshBuilder.CreateCylinder("cylinder", { height: 5, diameterTop: 1, diameterBottom: 2, tessellation: 36 }, scene);动态修改
js
box.scaling.x = 3; // 放大 x 轴方向
box.rotation.y = Math.PI / 4; // 绕 y 轴旋转 45 度
box.position.z = 3; // 移动到 z 轴方向 3 的位置高级功能 使用 MeshBuilder 创建网格实例,从而提高渲染性能
js
const boxTemplate = BABYLON.MeshBuilder.CreateBox("boxTemplate", { size: 1 }, scene);
const boxInstance = new BABYLON.Mesh("boxInstance", scene);
boxInstance.setParent(boxTemplate);合并几何体 Mesh.MergeMeshes 方法将多个网格合并成一个网格,减少绘制调用次数
js
const mergedMesh = BABYLON.Mesh.MergeMeshes([mesh1, mesh2, mesh3], true, true);高级几何体生成与顶点缓冲区设计
使用参数化函数创建几何体
创建螺旋体
js
const createSpiral = (turns: number, radius: number, height: number, scene: BABYLON.Scene) => {
const spiral = new BABYLON.Mesh("spiral", scene);
const positions: number[] = [];
const indices: number[] = [];
const segments = 100;
const angleStep = (2 * Math.PI) / segments;
const heightStep = height / (turns * segments);
for (let t = 0; t <= turns; t++) {
for (let i = 0; i <= segments; i++) {
const angle = i * angleStep;
const x = radius * Math.cos(angle);
const y = heightStep * t * segments + heightStep * i;
const z = radius * Math.sin(angle);
positions.push(x, y, z);
}
}
for (let t = 0; t < turns; t++) {
for (let i = 0; i < segments; i++) {
const a = t * (segments + 1) + i;
const b = a + segments + 1;
indices.push(a, b, a + 1);
indices.push(b, b + 1, a + 1);
}
}
spiral.setVerticesData(BABYLON.VertexBuffer.PositionKind, positions, false);
spiral.setIndices(indices);
spiral.computeNormals();
return spiral;
};
const spiral = createSpiral(5, 1, 5, scene);- 参数: 螺旋的圈数、半径、高度和所属场景。
- positions: 存储顶点位置数据。
- indices: 存储索引数据,用于定义三角面。
- setVerticesData: 设置顶点数据。
- setIndices: 设置索引数据。
- computeNormals: 计算法线向量。
使用自定义顶点数据创建几何体
js
const createCustomPlane = (width: number, height: number, segments: number, scene: BABYLON.Scene) => {
const plane = new BABYLON.Mesh("customPlane", scene);
const positions: number[] = [];
const normals: number[] = [];
const uvs: number[] = [];
const indices: number[] = [];
const widthStep = width / segments;
const heightStep = height / segments;
for (let i = 0; i <= segments; i++) {
for (let j = 0; j <= segments; j++) {
const x = -width / 2 + i * widthStep;
const y = 0;
const z = -height / 2 + j * heightStep;
positions.push(x, y, z);
normals.push(0, 1, 0);
uvs.push(i / segments, j / segments);
}
}
for (let i = 0; i < segments; i++) {
for (let j = 0; j < segments; j++) {
const a = i * (segments + 1) + j;
const b = a + segments + 1;
indices.push(a, b, a + 1);
indices.push(b, b + 1, a + 1);
}
}
plane.setVerticesData(BABYLON.VertexBuffer.PositionKind, positions, false);
plane.setVerticesData(BABYLON.VertexBuffer.NormalKind, normals, false);
plane.setVerticesData(BABYLON.VertexBuffer.UVKind, uvs, false);
plane.setIndices(indices);
return plane;
};
const customPlane = createCustomPlane(5, 5, 100, scene);- 参数: 平面的宽度、高度、细分段数和所属场景。
- positions: 存储顶点位置数据。
- normals: 存储法线向量数据。
- uvs: 存储纹理坐标数据。
- indices: 存储索引数据,用于定义三角面。
- setVerticesData: 设置不同类型的顶点数据。
使用顶点缓冲区 (Vertex Buffer) 创建几何体
js
const createWavePlane = (width: number, height: number, segments: number, scene: BABYLON.Scene) => {
const plane = new BABYLON.Mesh("wavePlane", scene);
const positions = new Float32Array((segments + 1) * (segments + 1) * 3);
const normals = new Float32Array((segments + 1) * (segments + 1) * 3);
const uvs = new Float32Array((segments + 1) * (segments + 1) * 2);
const indices = new Uint32Array(segments * segments * 6);
const widthStep = width / segments;
const heightStep = height / segments;
for (let i = 0; i <= segments; i++) {
for (let j = 0; j <= segments; j++) {
const x = -width / 2 + i * widthStep;
const y = Math.sin(Math.sqrt(x * x + (i * heightStep) * (i * heightStep))) * 0.5;
const z = -height / 2 + j * heightStep;
const index = i * (segments + 1) + j;
positions[index * 3] = x;
positions[index * 3 + 1] = y;
positions[index * 3 + 2] = z;
normals[index * 3] = 0;
normals[index * 3 + 1] = 1;
normals[index * 3 + 2] = 0;
uvs[index * 2] = i / segments;
uvs[index * 2 + 1] = j / segments;
}
}
for (let i = 0; i < segments; i++) {
for (let j = 0; j < segments; j++) {
const a = i * (segments + 1) + j;
const b = a + segments + 1;
indices[i * segments * 6 + j * 6] = a;
indices[i * segments * 6 + j * 6 + 1] = b;
indices[i * segments * 6 + j * 6 + 2] = a + 1;
indices[i * segments * 6 + j * 6 + 3] = b;
indices[i * segments * 6 + j * 6 + 4] = b + 1;
indices[i * segments * 6 + j * 6 + 5] = a + 1;
}
}
plane.setVerticesData(BABYLON.VertexBuffer.PositionKind, positions, false);
plane.setVerticesData(BABYLON.VertexBuffer.NormalKind, normals, false);
plane.setVerticesData(BABYLON.VertexBuffer.UVKind, uvs, false);
plane.setIndices(indices);
return plane;
};
const wavePlane = createWavePlane(10, 10, 100, scene);- 波浪形平面: 通过对 y 坐标应用正弦函数,生成波浪形状。
- 顶点缓冲区: 使用 Float32Array 和 Uint32Array 来存储顶点数据。
- setVerticesData: 设置顶点数据,包括位置、法线和纹理坐标。
- setIndices: 设置索引数据。
性能优化
优先使用索引网格
js
const box = BABYLON.MeshBuilder.CreateBox("box", { size: 2 }, scene);
// 转换为非索引网格(不推荐)
box.setIndices(null);顶点缓存优化
js
const boxTemplate = BABYLON.MeshBuilder.CreateBox("boxTemplate", { size: 1 }, scene);
const boxInstance1 = new BABYLON.Mesh("boxInstance1", scene);
boxInstance1.setParent(boxTemplate);
const boxInstance2 = new BABYLON.Mesh("boxInstance2", scene);
boxInstance2.setParent(boxTemplate);Mesh.MergeMeshes 方法将多个网格合并成一个网格,减少绘制调用次数
js
const mergedMesh = BABYLON.Mesh.MergeMeshes([mesh1, mesh2, mesh3], true, true);