three | 材质 Material

之前讲的都是几何体 Geometry 的相关知识,本文说一说"材质 Material "。

通过之前的代码可以知道,对于一些封装好的模型,three 提供了专门的方法。比如点模型的材质方法:

javascript 复制代码
const material = new THREE.PointsMaterial({
 color: new THREE.Color('orange'),
 size: 10
});

线模型的材质方法:

javascript 复制代码
const material = new THREE.LineBasicMaterial({
 color: new THREE.Color('orange')
});

还有网格模型的材质方法(不受光照影响):

javascript 复制代码
const material = new THREE.MeshBasicMaterial(({
 color: new THREE.Color('orange'),
 wireframe: true,
}));

同一种几何体,加上不同的材质,就可以渲染出不同的效果。

下面我们依旧是学一下 Material 的通用属性:color 颜色、map 颜色贴图 。

javascript 复制代码
import * as THREE from 'three';
const geometry = new THREE.PlaneGeometry(100, 100);
const material = new THREE.MeshBasicMaterial(({
 color: new THREE.Color('orange')
}));
const mesh = new THREE.Mesh(geometry, material);
console.log(mesh);
export default mesh;

这是一个经典的网格模型,设置了color。我们再来看下控制台打印:

mesh 除了 geometry 属性,也有 material 属性。

material.color 是一个 Color 对象,我们可以用各种 get 方法拿到它的颜色值:

javascript 复制代码
console.log(color.getHSL());
console.log(color.getHex());
console.log(color.getRGB());
console.log(color.getHexString());
console.log(color.getStyle());

还可以用各种 set 方法修改颜色值:

javascript 复制代码
color.setStyle('blue');

如果我们希望材质有一定透明度,也可以用 transparent :

javascript 复制代码
constmaterial =newTHREE.MeshBasicMaterial(({
	color:newTHREE.Color('orange'),
	transparent:true,
	opacity:0.5
}));

但也有一些时候,我们不是要设置颜色,而是要设置一张图片。这时候可以用 map 属性:

javascript 复制代码
import * as THREE from 'three';

const loader = new THREE.TextureLoader();
const texture = loader.load('./haha.png');
const geometry = new THREE.SphereGeometry(100);
const material = new THREE.MeshBasicMaterial({
    map: texture
});
const mesh =new THREE.Mesh(geometry, material);

export default mesh;

SphereGeometry 是球体:

如果这时候我们再在 MeshBasicMaterial 中加入:

javascript 复制代码
color:newTHREE.Color('orange'),

设置平面物体 PlaneGeometry 效果也是一样:

javascript 复制代码
import * as THREE from 'three';

const loader = new THREE.TextureLoader();
const texture = loader.load('./haha.png');
texture.wrapS=THREE.RepeatWrapping
texture.wrapT=THREE.RepeatWrapping
texture.repeat.set(3,3);
const geometry = new THREE.PlaneGeometry(1000, 1000);
const material = new THREE.MeshBasicMaterial({
    map: texture
});
const mesh =new THREE.Mesh(geometry, material);

export default mesh;

不过在设置平面物体时一定要考虑一点:相机视角!

如果你在调用上面这个代码后相机那里还按之前的这么写:

javascript 复制代码
const camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000);

根据上上一片文章中说到的"近截面远截面"的知识,你得到的大概率是一个很有倾斜角度、展示不完全的图片,但是如果我们让物体远一点:

javascript 复制代码
const camera = new THREE.PerspectiveCamera(60, width / height, 1, 10000);

这样就不会被裁剪了。所以你经常看到代码里近裁截面设置了 0.1,远裁截面设置了好几万,就是为了让视椎体的范围能覆盖全部场景。

我们还可以修改相机的位置达到效果:

javascript 复制代码
camera.position.set(90, 200, 1000);

那如果我们想让图片在水平/垂直方向重复呢?直接设置在水平(wrapS)和竖直(wrapT)方向重复,然后设置重复次数就可以了:

javascript 复制代码
const texture = loader.load('./haha.png');
texture.wrapS=THREE.RepeatWrapping
texture.wrapT=THREE.RepeatWrapping
texture.repeat.set(3,3);

写到这我发现一件事,这贴图怎么这么泛白,原图是有很深的颜色的。于是我找到了这个方法:

javascript 复制代码
texture.colorSpace=THREE.SRGBColorSpace;

修改图片对象的颜色空间。

但是直到这里,图片依然"失真",这里说的不是图片本身和原图的真假,而是和现实的真假。因为我们是有"光照"的,如果是模型线条本身也是可以的,但这里是贴图, map 只是把贴图的颜色加上去了,没有做进一步的处理,如果你想要那种受环境光影响的凹凸感,需要设置 aoMap 属性:

javascript 复制代码
const material = new THREE.MeshBasicMaterial({
    map: texture,
    aoMap: texture   // 重点!!!
});
相关推荐
涛涛ing4 小时前
你的页面为什么总是卡成PPT?2026年,90%的前端都忽略了主线程
前端
SoaringHeart4 小时前
Flutter 进阶 | 组件封装:用 CustomPainter 实现光环动画组件AnimatedHalo
前端·flutter
IT_陈寒4 小时前
JavaScript的隐式转换太坑了,我的==比较怎么就炸了?
前端·人工智能·后端
雪芽蓝域zzs4 小时前
第十四节:后端返回权限动态路由
前端·javascript·vue.js
小磊哥er4 小时前
Wonder Claude Code - 一个可运行的、教学级的 Claude Code 精简复刻
javascript·ai编程
Rain5094 小时前
谁动了我的 URL?——记一次微前端“灵异 Bug“的排查实录
前端·vue.js·人工智能·前端框架·bug·ai编程
bjzhang755 小时前
使用HTML+CSS美化上传进度条展示
前端·css·html
何以解忧,唯有..5 小时前
Vue 3 响应式核心:ref() 与 reactive() 的深入解析与实战
前端·javascript·vue.js
晴天165 小时前
Chrome DevTools Protocol(CDP)分享-Day36
前端·chrome·chrome devtools
风骏时光牛马5 小时前
程序员的职场成长:技术之外,更要修炼底层思考力
前端