首页 > 其他分享 >three.js教程7-PBR材质与环境贴图

three.js教程7-PBR材质与环境贴图

时间:2023-02-09 21:11:25浏览次数:58  
标签:贴图 PBR 环境 three jpg THREE 材质 gltf

1、PBR材质

PBR是基于物理的渲染(physically-based rendering)。模拟物体表面的反射算法。

Three.js提供了两个PBR材质相关的类MeshStandardMaterialMeshPhysicalMaterial

MeshPhysicalMaterialMeshStandardMaterial扩展的子类,提供了更多功能属性。

PBR材质相比MeshLambertMaterial和MeshPhongMaterial可以提供更逼真的、更接近生活中的材质效果,当然也会占用更多的电脑硬件资源。

  PBR相关理论介绍文章

半小时了解PBR:https://zhuanlan.zhihu.com/p/37639418

PBR知识体系整理:https://zhuanlan.zhihu.com/p/100596453

PBR核心知识体系总结与概览:https://zhuanlan.zhihu.com/p/53086060

2、MeshStandardMaterial材质实现金属效果

(1)  金属度metalness、粗糙度roughness

//金属度
//默认是0.5,范围是0到1之间。木材或石材用0,金属使用1。
mesh.material.metalness = 1.0;
//表面粗糙度
//默认0.5,范围是0~1之间,0表示平滑的镜面反射,1表示完全漫反射,
mesh.material.roughness = 0.5;

(2)环境贴图.envMap=CubeTextureLoader()立方体纹理加载器加载环境贴图

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

// 加载环境贴图
// 加载周围环境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 
new THREE.MeshStandardMaterial({
    metalness: 1.0,
    roughness: 0.5,
    envMap: textureCube, //设置pbr材质环境贴图
})    

(3)环境贴图强度envMapIntensity-环境贴图反射率

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

(4)场景环境属性.environment

加载gltf模型后,如果你希望环境贴图影响场景中scene所有Mesh,1、可以循环遍历模型设置envMap,2、也可以通过Scene的场景环境属性.environment实现。

//方法1
loader.load("../工厂.glb", function (gltf) {
    // 递归遍历批量设置环境贴图
    gltf.scene.traverse(function (obj) {
        if (obj.isMesh) { //判断是否是网格模型
            obj.material.envMap = textureCube; //设置环境贴图
        }
    });
})
//方法2:
// 环境贴图纹理对象textureCube作为.environment属性值,影响所有模型
scene.environment = textureCube;

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

3、MeshPhysicalMaterial材质-新增属性

(1)清漆层clearcoat和清漆层粗糙度.clearcoatRoughness

clearcoat:模拟物体表面一层透明图层,类似车漆的抛光打蜡,具有透明和反光特性,值越大反光效果越好。clearcoatRoughness,值越大反光效果越弱。

const material = new THREE.MeshPhysicalMaterial( {
    clearcoat: 1.0,//半透明涂层的厚度,默认是0,范围是0~1m
    clearcoatRoughness: 0.1,//半透明涂层表面的粗糙度,默认是0,范围是0~1
} );

(2) 玻璃的透光率(透射度).transmission

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

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

(3) 折射率ior

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

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

new THREE.MeshPhysicalMaterial({
    ior:1.5,//折射率
})

(4)反射率.reflectivity、光泽.sheen

4、三维软件导出PBR材质属性

实际开发的时候PBR材质的属性,很多时候是可以在三维建模软件中设置的,然后通过gltf导出即可,这样就不用在threejs代码设置。

通常美术对三维场景渲染的了解也比大部分前端程序员多的多,只要美术在三维建模软件设置好并导出包含pbr材质属性的gltf即可。

(1)threejs解析gltf材质规则

threejs解析gltf模型材质的时候,一般默认使用标准网格材质MeshStandardMaterial,如果gltf有的材质具有.clearcoat.transmission等属性,标准网格材质MeshStandardMaterial无法表达的时候,会用物理网格材质MeshPhysicalMaterial来解析gltf材质。

(2)设置环境贴图

这时候清漆、清漆粗糙度、透光率(透射度)等属性Bledner都已经设置好了,threejs可以自动解析渲染,不用在代码中麻烦设置了,只要配上环境贴图即可。

// 加载环境贴图
const textureCube = new THREE.CubeTextureLoader()
    .setPath('../../环境贴图/环境贴图1/')
    .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);
textureCube.encoding = THREE.sRGBEncoding; //设置纹理贴图编码方式和WebGL渲染器一致    
// 加载gltf模型,然后给指定模型设置环境贴图
loader.load("../../轿车.glb", function (gltf) {
    model.add(gltf.scene);
    const mesh = gltf.scene.getObjectByName('玻璃01');
    mesh.material.envMap=textureCube;
    mesh.material.envMapIntensity=1.0;
})

 

示例1:金属效果

 

const model = new THREE.Group(); //声明一个组对象,用来添加加载成功的三维场景
// 加载环境贴图
// 加载周围环境6个方向贴图
// 上下左右前后6张贴图构成一个立方体空间
// 'px.jpg', 'nx.jpg':x轴正方向、负方向贴图  p:正positive  n:负negative
// 'py.jpg', 'ny.jpg':y轴贴图
// 'pz.jpg', 'nz.jpg':z轴贴图
// CubeTexture表示立方体纹理对象,父类是纹理对象Texture
const textureCube = new THREE.CubeTextureLoader()
    .setPath('../../环境贴图/环境贴图1/')
    .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);


const loader = new GLTFLoader(); //创建一个GLTF加载器
loader.load("../../金属.glb", function (gltf) {
    // 递归遍历所有模型节点批量修改材质
    gltf.scene.traverse(function (obj) {
        if (obj.isMesh) { //判断是否是网格模型
            // console.log('obj.material',obj.material);
            // 重新设置材质的金属度和粗糙度属性
            obj.material.metalness = 1.0; //金属度
            obj.material.roughness = 0.3; //表面粗糙度
            obj.material.envMap = textureCube; //设置环境贴图
            // envMapIntensity:控制环境贴图对mesh表面影响程度
            obj.material.envMapIntensity = 1.0;//默认值1, 设置为0.0相当于没有环境贴图
        }
    });
    model.add(gltf.scene);
})

 

 示例2:车外壳油漆反光效果-清漆层属性clearcoat

const model = new THREE.Group(); //声明一个组对象,用来添加加载成功的三维场景
// 加载环境贴图
const textureCube = new THREE.CubeTextureLoader()
    .setPath('../../环境贴图/环境贴图1/')
    .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);

textureCube.encoding = THREE.sRGBEncoding; //设置纹理贴图编码方式和WebGL渲染器一致    

const loader = new GLTFLoader(); //创建一个GLTF加载器
loader.load("../../轿车.glb", function (gltf) {
    model.add(gltf.scene);
    // 车外壳包含多个Mesh,获取其中一个
    const mesh = gltf.scene.getObjectByName('外壳01');
    mesh.material = new THREE.MeshPhysicalMaterial({
        color: mesh.material.color, //默认颜色
        metalness: 0.9,//车外壳金属度
        roughness: 0.5,//车外壳粗糙度
        clearcoat: 1, //清漆层
        clearcoatRoughness: 0.01, //清漆层粗糙度
        envMap: textureCube, //环境贴图
        envMapIntensity: 2.5, //环境贴图对Mesh表面影响程度
    })
})

 

示例3:车玻璃效果-透光率transmission和折射率ior

const model = new THREE.Group(); //声明一个组对象,用来添加加载成功的三维场景
// 加载环境贴图
const textureCube = new THREE.CubeTextureLoader()
    .setPath('../../环境贴图/环境贴图1/')
    .load(['px.jpg', 'nx.jpg', 'py.jpg', 'ny.jpg', 'pz.jpg', 'nz.jpg']);
textureCube.encoding = THREE.sRGBEncoding; //设置纹理贴图编码方式和WebGL渲染器一致    

// 加载gltf模型
const loader = new GLTFLoader(); //创建一个GLTF加载器
loader.load("../../轿车.glb", function (gltf) {
    model.add(gltf.scene);
    const mesh = gltf.scene.getObjectByName('玻璃01')
    mesh.material = new THREE.MeshPhysicalMaterial({
        metalness: 0.0,//玻璃非金属 
        roughness: 0.0,//玻璃表面光滑
        envMap:textureCube,//环境贴图
        envMapIntensity: 1.0, //环境贴图对Mesh表面影响程度
        transmission: 1.0, //玻璃材质透光率,transmission替代opacity 
        ior:1.5,//折射率
    })
})

 

文章中部分素材选取自Threejs中文网:http://www.webgl3d.cn/

标签:贴图,PBR,环境,three,jpg,THREE,材质,gltf
From: https://www.cnblogs.com/tiandi/p/17087450.html

相关文章