七、Three.jsPBR材质与纹理贴图

1、PBR材质金属度和粗糙度

1、金属度 metalness

金属度 属性.metalness表示材质像金属的程度, 非金属材料,如木材或石材,使用0.0,金属使用1.0。

threejs的PBR材质,.metalness默认是0.5,0.0到1.0之间的值可用于生锈的金属外观

javascript 复制代码
new THREE.MeshStandardMaterial({
    metalness: 1.0,//金属度属性
})
javascript 复制代码
mesh.material.metalness = 1.0;//金属度

2、粗糙度 roughness

生活中不同物体表面的粗糙程度不同,比如地面比较粗糙,比如镜子表面就非常非常光滑。

粗糙度 roughness表示模型表面的光滑或者说粗糙程度,越光滑镜面反射能力越强,越粗糙,表面镜面反射能力越弱,更多地表现为漫反射。

粗糙度 roughness,0.0表示平滑的镜面反射,1.0表示完全漫反射,默认0.5。

javascript 复制代码
new THREE.MeshStandardMaterial({
    roughness: 0.5,//表面粗糙度
})
javascript 复制代码
mesh.material.roughness = 0.5;//表面粗糙度

3、全部代码

原本样式

javascript 复制代码
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const loader = new GLTFLoader()
const group = new THREE.Group()
loader.load('./build/金属.glb', function (gltf) {
    gltf.scene.traverse(function (obj) {
        if(obj.isMesh){
            obj.material.metalness = 1.0
            obj.material.roughness = 0.5
        }
    })
    group.add(gltf.scene)
})

export default group 

2、环境贴图.envMap(金属效果)

环境贴图对PBR材质渲染效果影响还是比较大,一般渲染PBR材质的模型,最好设置一个合适的环境贴图。

1、立方体纹理加载器CubeTextureLoader

  • TextureLoader返回Texture
  • CubeTextureLoader返回CubeTexture

2、CubeTextureLoader加载环境贴图

所谓环境贴图 ,就是一个模型周围的环境的图像,比如一间房子,房子的上下左右前后分别拍摄一张照片,就是3D空间中6个角度方向的照片。

javascript 复制代码
// 加载环境贴图
// 加载周围环境6个方向贴图
// 上下左右前后6张贴图构成一个立方体空间
// 'px.jpg', 'nx.jpg':x轴正方向、负方向贴图  p:正positive  n:负negative
// 'py.jpg', 'ny.jpg':y轴贴图
// 'pz.jpg', 'nz.jpg':z轴贴图
const textureCube = new THREE.CubeTextureLoader()
    .setPath('./环境贴图/环境贴图0/')
    .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);
    // CubeTexture表示立方体纹理对象,父类是纹理对象Texture 

3、MeshStandardMaterial环境贴图属性.envMap

实际生活中,一个物体表面,往往会反射周围的环境。人的眼睛看到的东西,往往反射有周围景物,所以three.js渲染模型,如果想渲染效果更好看,如果想更符合实际生活情况,也需要想办法让模型反射周围景物。

MeshStandardMaterial材质的环境贴图属性是.envMap,通过PBR材质的贴图属性可以实现模型表面反射周围景物,这样渲染效果更好。

javascript 复制代码
// 加载环境贴图
const textureCube = new THREE.CubeTextureLoader()
    .setPath('./环境贴图/环境贴图0/')
    .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);
new THREE.MeshStandardMaterial({
    metalness: 1.0,
    roughness: 0.5,
    envMap: textureCube, //设置pbr材质环境贴图
})    
javascript 复制代码
obj.material.envMap = textureCube; //设置环境贴图 

1、全部代码

javascript 复制代码
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const loader = new GLTFLoader()
const group = new THREE.Group()

//环境贴图
const textureCube = new THREE.CubeTextureLoader()
.setPath('./build/环境贴图1/')
.load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);

loader.load('./build/金属.glb', function (gltf) {
    gltf.scene.traverse(function (obj) {
        if(obj.isMesh){
            obj.material.metalness = 1.0
            obj.material.roughness = 0
            obj.material.envMap = textureCube
        }
    })
    group.add(gltf.scene)
})

export default group 

2、环境贴图反射率.envMapIntensity

MeshStandardMaterial.envMapIntensity属性主要用来设置模型表面反射周围环境贴图的能力,或者说环境贴图对模型表面的影响能力。具体说.envMapIntensity相当于环境贴图的系数,环境贴图像素值乘以该系数后,在用于影响模型表面。

javascript 复制代码
// envMapIntensity:控制环境贴图对mesh表面影响程度
//默认值1, 设置为0.0,相当于没有环境贴图
obj.material.envMapIntensity = 1.0;

3、粗糙度 roughness为0

你可以尝试把粗糙度 roughness设置为0,看看模型对环境贴图的反射效果。

javascript 复制代码
obj.material.roughness = 0.0;//完全镜面反射,像镜子一样

4、纹理和渲染器颜色空间一致

javascript 复制代码
//如果renderer.outputEncoding=THREE.sRGBEncoding;环境贴图需要保持一致
textureCube.encoding = THREE.sRGBEncoding;   

4、环境贴图2

1、环境贴图作用测试

实际生活中光源照射到一个物体上,这个物体反射出去的光线也会影响其他的物体,环境贴图就是用一种简单方式,近似模拟一个物体周边环境对物体表面的影响。

测试:对于PBR材质,如果threejs三维场景不添加任何光源,物体就是完全黑色的,你可以不添加任何光源,尝试只使用环境贴图,你会发现物体表面的颜色也能看到,这说明环境贴图其实相当于提供了物体周围环境发射或反射的光线。

测试:更换不同明暗的环境贴图,你会发现场景中模型的明暗也有变化。

1、场景环境属性.environment

网格模型可以通过材质的.envMap属性设置环境贴图,如果一个gltf模型中所有的Mesh都要设置环境贴图就需要递归遍历gltf模型,给里面每个Mesh的材质设置.envMap

javascript 复制代码
loader.load("../工厂.glb", function (gltf) {
    // 递归遍历批量设置环境贴图
    gltf.scene.traverse(function (obj) {
        if (obj.isMesh) { //判断是否是网格模型
            obj.material.envMap = textureCube; //设置环境贴图
        }
    });
})

如果你希望环境贴图影响场景中scene所有Mesh,可以通过Scene的场景环境属性.environment实现,把环境贴图对应纹理对象设置为.environment的属性值即可。

javascript 复制代码
// 环境贴图纹理对象textureCube作为.environment属性值,影响所有模型
scene.environment = textureCube;

2、环境贴图色彩空间编码.encoding

javascript 复制代码
//如果renderer.outputEncoding=THREE.sRGBEncoding;环境贴图需要保持一致
textureCube.encoding = THREE.sRGBEncoding;   

注意:设置环境贴图后可以不设置光源,也可以显示出物体的样式

5、MeshPhysicalMaterial清漆层

MeshPhysicalMaterialMeshStandardMaterial都是拥有金属度metalness、粗糙度roughness属性的PBR材质,MeshPhysicalMaterial是在MeshStandardMaterial基础上扩展出来的子类,除了继承了MeshStandardMaterial的金属度、粗糙度等属性,还新增了清漆.clearcoat、透光率.transmission、反射率.reflectivity、光泽.sheen、折射率.ior等等各种用于模拟生活中不同材质的属性。

1、清漆层属性.clearcoat

清漆层属性.clearcoat可以用来模拟物体表面一层透明图层,就好比你在物体表面刷了一层透明清漆,喷了点水。.clearcoat的范围0到1,默认0。

javascript 复制代码
const material = new THREE.MeshPhysicalMaterial( {
	clearcoat: 1.0,//物体表面清漆层或者说透明涂层的厚度
} );

2、清漆层粗糙度.clearcoatRoughness

清漆层粗糙度.clearcoatRoughness属性表示物体表面透明涂层.clearcoat对应的的粗糙度,.clearcoatRoughness的范围是为0.0至1.0。默认值为0.0。

javascript 复制代码
const material = new THREE.MeshPhysicalMaterial( {
	clearcoat: 1.0,//物体表面清漆层或者说透明涂层的厚度
	clearcoatRoughness: 0.1,//透明涂层表面的粗糙度
} );

3、车外壳PBR材质设置

在设置车外壳清漆层之前,先创建一个MeshPhysicalMaterial材质,并设置好环境贴图、金属度、粗糙度,属性值先根据文档说明给一个大概的值,具体可以通过gui交互界面可视化调试。

javascript 复制代码
const mesh = gltf.scene.getObjectByName('外壳01');
mesh.material = new THREE.MeshPhysicalMaterial({
        color: mesh.material.color, //默认颜色
        metalness: 0.9,//车外壳金属度
        roughness: 0.5,//车外壳粗糙度
        envMap: textureCube, //环境贴图
        envMapIntensity: 2.5, //环境贴图对Mesh表面影响程度
})  

4、全部代码

javascript 复制代码
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const group = new THREE.Group();
const textureCube = new THREE.CubeTextureLoader().setPath('./build/环境贴图1/').load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg'])
textureCube.encoding = THREE.sRGBEncoding;

const loader = new GLTFLoader();
loader.load('./build/轿车.glb', function (glb) {
    const mesh = glb.scene.getObjectByName('外壳01')
    mesh.material = new THREE.MeshPhysicalMaterial({
        color:mesh.material.color,
        // color:'red',
        metalness:1,//金属度
        roughness:0.5,//粗糙度
        envMap:textureCube,
        envMapIntensity:2.0,
        clearcoat:1.0,//清漆
        clearcoatRoughness:0.1,//清漆层粗糙度
    })
    group.add(glb.scene)
})

export default group 

6、物理材质透光率.transmission

1、透光率(透射度).transmission

为了更好的模拟玻璃、半透明塑料一类的视觉效果,可以使用物理透明度.transmission属性代替Mesh普通透明度属性.opacity

使用.transmission属性设置Mesh透明度,即便完全透射的情况下仍可保持高反射率。

物理光学透明度.transmission的值范围是从0.0到1.0。默认值为0.0。

javascript 复制代码
const mesh = gltf.scene.getObjectByName('玻璃01')
mesh.material = new THREE.MeshPhysicalMaterial({
    transmission: 1.0, //玻璃材质透光率,transmission替代opacity 
})

2、折射率.ior

非金属材料的折射率从1.0到2.333。默认值为1.5。

不同材质的折射率,你可以百度搜索。

javascript 复制代码
new THREE.MeshPhysicalMaterial({
    ior:1.5,//折射率
})

3、玻璃透光率.transmission设置

先设置玻璃金属度和粗糙度

javascript 复制代码
const mesh = gltf.scene.getObjectByName('玻璃01')
mesh.material = new THREE.MeshPhysicalMaterial({
    metalness: 0.0,//玻璃非金属 
    roughness: 0.0,//玻璃表面光滑
    envMap:textureCube,//环境贴图
    envMapIntensity: 1.0, //环境贴图对Mesh表面影响程度
})

设置透光率.transmission和折射率.ior

javascript 复制代码
new THREE.MeshPhysicalMaterial({
    transmission: 1.0, //玻璃材质透光率,transmission替代opacity 
    ior:1.5,//折射率
})

4、全部代码

javascript 复制代码
import * as THREE from 'three';
import { GLTFLoader } from 'three/addons/loaders/GLTFLoader.js';

const group = new THREE.Group();
const textureCube = new THREE.CubeTextureLoader().setPath('./build/环境贴图1/').load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg'])
textureCube.encoding = THREE.sRGBEncoding;

const loader = new GLTFLoader();
loader.load('./build/轿车.glb', function (glb) {
    const mesh = glb.scene.getObjectByName('外壳01')
    mesh.material = new THREE.MeshPhysicalMaterial({
        color:mesh.material.color,
        // color:'red',
        metalness:1,//金属度
        roughness:0.5,//粗糙度
        envMap:textureCube,
        envMapIntensity:2.0,
        clearcoat:1.0,//清漆
        clearcoatRoughness:0.1,//清漆层粗糙度

    })

    const mesh1 = glb.scene.getObjectByName('玻璃01')
    mesh1.material = new THREE.MeshPhysicalMaterial({
        color:mesh1.material.color,
        metalness:0.0,//金属度
        roughness:0.0,//粗糙度,
        envMap:textureCube,
        envMapIntensity:1.0,
        transmission:1.0,//透光率
        ior:1.5,//折射率
    })
    group.add(glb.scene)
})

export default group 
相关推荐
子琦啊10 小时前
构造函数、this指向和原型链机制
javascript·算法·贴图
Nan-h113 小时前
Mac 剪贴板工具选型:先看工作流,再看 Maccy、Raycast、Paste 和 uPaste
macos·贴图
CG_MAGIC2 天前
主流 3D 软件文件互通互导教程
3d·材质·效果图·建模教程·渲云渲染
吴梓穆2 天前
UE5 材质参数集
ue5·材质
摄影图3 天前
科技企业研发宣传图片素材 适配多场景宣传使用需求
大数据·人工智能·科技·aigc·贴图·插画
摄影图3 天前
AI设计实用图片素材 适配多元创作推广需求
人工智能·科技·智能手机·aigc·贴图
摄影图5 天前
太空站宇宙地球高清素材 适配科普宣传多类创作需求
科技·aigc·贴图·插画
摄影图6 天前
蓝色光效科技背景图片素材 多场景设计
人工智能·科技·aigc·贴图·插画
阿斯加德D6 天前
我的世界生活大冒险整合包下载高版本2026最新分享
测试工具·游戏·游戏程序·生活·材质
BSD_HY7 天前
薄膜开关技术深度解析:PET与PC材质对比、工业4.0接口设计及汽车电子产品应用
汽车·人机交互·制造·材质·薄膜开关