【three.js系列五】入门教程——网格材质与网络贴图

1,013 阅读3分钟

网格材质

网格材质(MeshMaterial)是 Three.js 中用于给网格模型赋予外观的材质。它可以控制模型的颜色、光泽度、透明度等属性。

Three.js 提供了多种网格材质,包括:

  • 基础网格材质(MeshBasicMaterial):  最简单的网格材质,仅支持颜色和透明度属性。
  • 朗伯网格材质(MeshLambertMaterial):  支持漫反射光照模型,可以模拟物体表面对光线的漫反射效果。
  • 冯格网格材质(MeshPhongMaterial):  支持漫反射和镜面反射光照模型,可以模拟物体表面对光线的漫反射和镜面反射效果。
  • 标准网格材质(MeshStandardMaterial):  基于物理的材质,可以模拟物体表面的真实光照效果。

网络贴图

网络贴图(Texture)是指从网络上加载的图像,用于赋予模型更逼真的外观。

Three.js 支持加载各种格式的网络贴图,包括:

  • PNG
  • JPEG
  • GIF
  • DDS

使用网络贴图

要使用网络贴图,需要先创建一个 TextureLoader 对象,然后使用该对象加载贴图。

const loader = new THREE.TextureLoader();

const texture = loader.load('https://example.com/texture.png');

加载完成后,可以将贴图应用于网格材质的 map 属性。

const material = new THREE.MeshBasicMaterial({
  map: texture,
});

网络贴图类型

常见的网络贴图类型包括:

  • 漫反射贴图(Diffuse Map):  用于模拟物体表面的漫反射光照效果。
  • 法线贴图(Normal Map):  用于模拟物体表面的凹凸不平效果。
  • 高光贴图(Specular Map):  用于模拟物体表面的高光效果。
  • 金属贴图(Metalness Map):  用于模拟物体表面的金属质感。
  • 粗糙度贴图(Roughness Map):  用于模拟物体表面的粗糙度。

环境贴图

创建纹理,环境的6个面顺序分别是:左右上下后前

const textures = new THREE.CubeTextureLoader()
  .setPath("./assets/textures/")
  .load(["04.jpg", "01.jpg", "05.jpg", "02.jpg", "06.jpg", "03.jpg"]);

立方体贴图

需要设置水平和垂直方向的环绕模式

const texture = new THREE.TextureLoader().load("./assets/textures/02-map.jpg");

// 纹理的环绕模式和重复因子

// 纹理 S 坐标(水平方向)的环绕模式
textures.wrapS = THREE.RepeatWrapping;
// 纹理 T 坐标(垂直方向)的环绕模式
textures.wrapT = THREE.RepeatWrapping;
// 纹理将在水平方向重复 4 次,在垂直方向重复 4 次
texture.repeat.set(4, 4);

添加场景背景

// 添加背景颜色
scene.background = new THREE.Color(0x666666);

// 或者添加环境贴图材质后再设置为背景
scene.background = textures;

完整代码

import * as THREE from "three";
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

const scene = new THREE.Scene();

// c
const textures = new THREE.CubeTextureLoader()
  .setPath("./assets/textures/")
  .load(["04.jpg", "01.jpg", "05.jpg", "02.jpg", "06.jpg", "03.jpg"]);

  // 立方体贴图
const texture = new THREE.TextureLoader().load("./assets/textures/02-map.jpg");

// 纹理的环绕模式和重复因子

// 纹理 S 坐标(水平方向)的环绕模式
textures.wrapS = THREE.RepeatWrapping;
// 纹理 T 坐标(垂直方向)的环绕模式
textures.wrapT = THREE.RepeatWrapping;
// 纹理将在水平方向重复 4 次,在垂直方向重复 4 次
texture.repeat.set(4, 4);

scene.background = textures;

/**
 * 添加雾 
 * 
 * 参数:
 * color :比如说,如果将其设置为黑色,远处的物体将被渲染成黑色。
 * near:开始应用雾的最小距离。距离小于活动摄像机“near”个单位的物体将不会被雾所影响。默认值是1。
 * far:结束计算、应用雾的最大距离,距离大于活动摄像机“far”个单位的物体将不会被雾所影响。默认值是1000。
 * */

scene.fog = new THREE.Fog(0xcccccc, 10, 15);

const camera = new THREE.PerspectiveCamera();
camera.position.y = 5;
camera.position.z = 10;

const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ map: texture });

const cube = new THREE.Mesh(geometry, material);
cube.position.set(0, 0, 0);
scene.add(cube);

const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

const controls = new OrbitControls(camera, renderer.domElement);
function animate() {
  requestAnimationFrame(animate);

  cube.rotation.x += 0.01;
  cube.rotation.y += 0.01;

  controls.update();
  renderer.render(scene, camera);
}
animate();


效果图如下:

image.png

所需图片如下,需要可自取:

01.jpg

02-map.jpg

02.jpg

03.jpg

04.jpg

05.jpg

06.jpg

资料来源:

b站