第一章 几何体与材质:从零搭建你的第一个3D世界
大家好,我是老张。做3D可视化这些年,我见过太多新手一上来就怼着复杂模型搞,结果连个立方体都渲染不出来。今天咱们就从最基础的几何体和材质聊起。说白了,这就是3D世界的「砖块」和「涂料」。
1.1 内置几何体:Three.js给你的「乐高积木」
Three.js内置了十几种基础几何体。我个人习惯把它们分成三类:
- 基础体:BoxGeometry(立方体)、SphereGeometry(球体)、CylinderGeometry(圆柱体)
- 扩展体:ConeGeometry(圆锥体)、TorusGeometry(圆环体)、TorusKnotGeometry(环面结)
- 平面类:PlaneGeometry(平面)、CircleGeometry(圆形)、RingGeometry(环形)
每个几何体都有自己的一套参数。拿BoxGeometry举例,它的构造函数长这样:
const geometry = new THREE.BoxGeometry(width, height, depth, widthSegments, heightSegments, depthSegments);
前三个参数控制尺寸,后三个控制细分段数。我在项目中遇到过一个问题:默认的立方体只有6个面,每个面2个三角形。如果你要做地形变形,就得增加细分段数。比如:
// 一个细分后的立方体,可以用于顶点动画
const geometry = new THREE.BoxGeometry(2, 2, 2, 10, 10, 10);
1.2 材质系统:给几何体「穿衣服」
材质决定了物体看起来是什么样子。Three.js的材质系统分两大类:
| 材质类型 | 特点 | 适用场景 |
|---|---|---|
| MeshBasicMaterial | 不受光照影响,纯色显示 | 调试、UI元素、低多边形风格 |
| MeshStandardMaterial | 基于物理渲染,支持光照 | 真实感场景、产品展示 |
| MeshPhongMaterial | 经典高光材质,性能较好 | 老项目兼容、中等画质 |
| MeshLambertMaterial | 漫反射材质,无高光 | 快速预览、低配设备 |
你想想看,如果场景里没有光源,用MeshStandardMaterial就是一片漆黑。这时候MeshBasicMaterial就派上用场了。我记得刚学Three.js时,死活看不到球体,折腾了半天才发现是忘了加光源。
1.3 颜色与纹理贴图:让物体「活」起来
颜色是最直接的视觉属性。Three.js支持三种颜色表示法:
// 十六进制(最常用)
const color = 0xff0000;
// 字符串
const color = 'red';
// Color对象
const color = new THREE.Color(1, 0, 0);
纹理贴图就更有意思了。说白了就是把一张图片「贴」到几何体表面。加载纹理的代码很简单:
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load('path/to/texture.jpg');
const material = new THREE.MeshStandardMaterial({
map: texture
});
1.4 实战:组合一个彩色立方体
光说不练假把式。咱们来写一个完整的示例:
// 1. 创建场景、相机、渲染器
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
// 2. 创建几何体
const geometry = new THREE.BoxGeometry(1, 1, 1);
// 3. 创建材质(带纹理)
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load('wood.jpg');
const material = new THREE.MeshStandardMaterial({
map: texture,
color: 0x8B4513, // 叠加棕色
roughness: 0.7,
metalness: 0.1
});
// 4. 组合成网格对象
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);
// 5. 添加光源
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5, 5, 5);
scene.add(light);
// 6. 渲染循环
function animate() {
requestAnimationFrame(animate);
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
renderer.render(scene, camera);
}
animate();
这段代码里,我用了MeshStandardMaterial配合纹理贴图。roughness控制粗糙度,metalness控制金属感。这两个参数配合好了,木头、石头、金属都能模拟出来。
1.5 材质属性的「调色盘」
除了map纹理,材质还有很多可调属性。我整理了一份常用清单:
- color:基础颜色,与纹理混合
- map:漫反射纹理
- normalMap:法线贴图,制造凹凸感
- roughness:粗糙度(0-1),0最光滑
- metalness:金属度(0-1),1最像金属
- emissive:自发光颜色
- transparent:是否透明
- opacity:透明度(0-1)
核心要点:几何体决定形状,材质决定外观。两者组合起来,就是3D世界的基本单元。别小看这些基础东西,我见过很多高级可视化项目,底层就是这些几何体堆出来的。
1.6 本章小结
嗯,到这里第一章就差不多了。咱们聊了内置几何体的参数、材质系统的分类、颜色和纹理的使用。最后还手写了一个完整的示例。下一章我会讲光源和阴影,到时候这些材质才能真正发挥威力。
对了,有个小建议:别光看代码,自己动手改改参数。把BoxGeometry改成SphereGeometry,把纹理换成纯色,看看效果有什么不同。实践出真知嘛。
公众号:蓝海资料掘金营,微信deep3321