2、基础材质(MeshBasicMaterial):属性详解
好,咱们今天聊聊 Three.js 里最基础、也最容易被轻视的材质——MeshBasicMaterial。
说实话,我刚学 Three.js 那会儿,觉得这玩意儿太简单了,不就是个纯色填充吗?后来做项目多了才发现,越是基础的东西,用好了反而能出奇效。
2.1 核心特点:不受光照影响
这是 MeshBasicMaterial 最根本的特性。你想想看,场景里加再多灯光,点光源、平行光、环境光……它统统无视。
为什么会有这种材质?
因为不是所有物体都需要光照计算。比如 UI 元素、背景天空盒、或者一些纯色装饰物。你给它们加光照,反而显得多余,还浪费性能。
关键点:MeshBasicMaterial 直接使用颜色值或纹理颜色,不参与任何光照计算。它的颜色就是最终显示的颜色。
我记得有一次做移动端项目,场景里有一堆小图标。如果用标准材质,每个图标都得参与光照计算,帧率直接掉到 30 以下。换成 MeshBasicMaterial 后,帧率瞬间回到 60。嗯,这就是它的价值。
2.2 属性详解
2.2.1 color —— 颜色控制
最常用的属性,没有之一。你可以用十六进制、颜色字符串、或者 THREE.Color 对象来设置。
// 三种方式,效果一样
const material1 = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const material2 = new THREE.MeshBasicMaterial({ color: 'red' });
const material3 = new THREE.MeshBasicMaterial({ color: new THREE.Color('red') });
我个人习惯用十六进制,因为直观,而且从设计稿里复制颜色值也方便。
小技巧:如果你想让材质半透明,记得同时设置 transparent: true 和 opacity 属性。光设 opacity 是没用的。
2.2.2 map —— 纹理贴图
给材质贴上一张图片,这就是纹理映射。用法很简单:
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load('path/to/texture.jpg');
const material = new THREE.MeshBasicMaterial({ map: texture });
这里有个坑,我曾经踩过:纹理加载是异步的。如果你在纹理还没加载完时就渲染,物体会显示为黑色。解决办法是用 onLoad 回调,或者干脆用 LoadingManager 统一管理。
注意:纹理图片的尺寸最好是 2 的幂次方(如 512x512、1024x1024),否则在某些设备上会出现奇怪的拉伸或性能问题。
2.2.3 wireframe —— 线框模式
这个属性特别适合调试。设成 true 后,物体会显示为线框结构,方便你观察几何体的顶点和三角面分布。
const material = new THREE.MeshBasicMaterial({
color: 0x00ff00,
wireframe: true
});
我刚开始学 Three.js 时,经常用线框模式来理解复杂几何体的结构。比如一个球体,线框模式下你能清楚看到经纬线的分布方式。
不过要注意,线框模式下颜色属性依然有效,但纹理贴图会被忽略。
2.2.4 其他常用属性
| 属性名 | 类型 | 说明 |
|---|---|---|
| transparent | Boolean | 是否启用透明度,默认 false |
| opacity | Number | 透明度值,0~1,需配合 transparent: true |
| side | THREE.Side | 渲染哪一面:THREE.FrontSide(默认)、BackSide、DoubleSide |
| visible | Boolean | 是否可见,默认 true |
2.3 适用场景
聊完属性,咱们说说这材质到底用在哪儿。
2.3.1 UI 元素
游戏里的血条、按钮、提示文字……这些都不需要光照。用 MeshBasicMaterial 渲染,性能好,颜色也准确。
我之前做过一个数据可视化项目,所有标签和图标都用这个材质。因为 UI 元素需要颜色稳定,不受场景灯光影响。你想想看,如果按钮颜色随着灯光变化,用户会疯掉的。
2.3.2 天空盒
天空盒说白了就是一个巨大的盒子,把场景包在里面。它不需要光照,因为天空本身就是光源。
// 天空盒材质示例
const skyMaterial = new THREE.MeshBasicMaterial({
map: skyTexture,
side: THREE.BackSide // 从内部看
});
这里有个细节:天空盒的材质要设置 side: THREE.BackSide,因为相机在盒子内部,我们需要看到盒子的内表面。
2.3.3 调试与预览
开发阶段,用 MeshBasicMaterial 快速搭建场景原型,等布局确定后再换成标准材质。这样能省下不少调试时间。
2.3.4 纯色装饰物
比如地面网格、辅助线、或者一些抽象几何体。这些物体不需要真实感渲染,用基础材质就够了。
2.4 避坑指南
最后分享几个我踩过的坑:
- 纹理不显示? 检查纹理路径是否正确,以及图片是否跨域(如果从外部加载)。
- 颜色不对? 确认没有误设
emissive属性——那是标准材质才有的。 - 性能问题? 如果场景里大量使用
MeshBasicMaterial,可以考虑合并几何体,减少 draw call。
我的习惯:每个新项目开始前,我都会先用 MeshBasicMaterial 搭一个快速原型。等所有物体位置、大小都调好了,再逐个替换成更复杂的材质。这样能避免在调试光照时还要反复调整位置,效率高很多。
好了,关于 MeshBasicMaterial 就聊这么多。下一章咱们会讲标准材质,那才是真正开始玩光照的地方。