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   // 重点!!!
});
相关推荐
JustHappy3 小时前
古法编程秘籍(七):互联网到底是什么?把两台电脑怎么说话搞懂就够了
前端·后端·网络协议
老毛肚3 小时前
jeecg-boot-base-core 02 day
javascript·python
snow@li3 小时前
SEO-文章标题:写文章时候,分类+主标题+大纲+解释 作为标题 / 不点进去也知道全文覆盖什么 / 标题即架构
前端
kyriewen4 小时前
Git Commit 前自动修复代码风格?配置 Husky + lint-staged,从此 CR 只聊逻辑
前端·git·面试
小和尚同志4 小时前
AI 自动化测试探索(一):Playwright MCP
前端·人工智能·aigc
老马识途2.05 小时前
在AI的帮助下理解spring的启动过程
java·前端·spring
徐小夕5 小时前
Loop Engineering 深度解析与实战指南(全网最全)
前端·算法·github
运筹vivo@6 小时前
Python ContextVar 底层机制与内存模型拆解
前端·数据库·python
#麻辣小龙虾#7 小时前
基于vue3.0开发一款【固废与废气运维管理系统】(支持源码)
前端·vue.js·vue3
Cosolar7 小时前
Docsify零构建文档站完全指南:从快速搭建到企业级部署
前端·开源·github