Three.js 快速入门教程【八】常见材质类型

news/2025/2/25 17:43:23

请添加图片描述

系列文章目录

Three.js 快速入门教程【一】开启你的 3D Web 开发之旅
Three.js 快速入门教程【二】透视投影相机
Three.js 快速入门教程【三】渲染器
Three.js 快速入门教程【四】三维坐标系
Three.js 快速入门教程【五】动画渲染循环
Three.js 快速入门教程【六】相机控件 OrbitControls
Three.js 快速入门教程【七】常见几何体类型
Three.js 快速入门教程【八】常见材质类型
Three.js 快速入门教程【九】光源类型


文章目录

  • 系列文章目录
  • 一、前言
  • 二、材质的基本概念
  • 三、光的基本概念
  • 四、常见材质类型
    • 1. MeshBasicMaterial(基础网格材质
      • 构造函数
      • 属性讲解
      • 示例
    • 2. MeshLambertMaterial(Lambert网格材质
      • 构造函数
      • 属性讲解
      • 示例
    • 3. MeshPhongMaterial(高光网格材质
      • 构造函数
      • 属性讲解
      • 示例
    • 4. MeshStandardMaterial(标准网格材质
      • 构造函数
      • 属性讲解
      • 示例
    • 5. MeshPhysicalMaterial(物理网格材质
      • 构造函数
      • 属性讲解
      • 示例
  • 五、通用的材质属性
    • 示例:带透明六面不同颜色正方体
  • 六、 材质的高级应用
    • 示例:纹理贴图——自转的地球
  • 五、总结


一、前言

      在 Three.js 的三维世界里,材质(Material)就像是给物体穿上的 “衣服”,它决定了物体如何与光线交互,以及最终呈现出的视觉效果。对于前端开发者来说,掌握材质的使用是构建逼真且富有表现力的 3D 场景的关键。本文将带你深入了解 Three.js 中常见的材质类型及其应用。


二、材质的基本概念

      在 Three.js 中,材质是 Material 类的实例,用于定义物体的外观属性。每个材质都包含了一些属性,如颜色、透明度、反射率等,这些属性会影响物体在场景中的渲染方式。材质与几何形状(Geometry)结合,才能创建出完整的物体。


三、光的基本概念

      在现实世界中,光是一种能量形式,通过照射物体并被物体反射进入我们的眼睛,使我们能够看到物体。在 three.js 的 3D 虚拟场景中,光同样起着类似的作用,它可以照亮场景中的物体,并且可以模拟不同类型的光照效果,如太阳光、点光源、聚光灯等。

ps:尽管光不是构建3D场景必须元素,但想构建逼真炫酷的3D场景是离不开光的,所以光在three.js开发中非常重要,这边只要了解什么是光以及记住光会影响材质就行了,后续有专门篇幅介绍光


四、常见材质类型

在这里插入图片描述

1. MeshBasicMaterial(基础网格材质

MeshBasicMaterial 是最简单的材质,它不受光照影响,始终以固定颜色显示。常用于调试或创建不需要光照效果的简单物体,适用场景例如:快速原型、辅助线框、UI元素等

如果你有阅读该系列教程前几篇文章,你就会发现示例中几何体粗糙模糊没棱角3d效果比较差,因为都是用了基础网格材质类型,基础材质在实际开发中还是比较少用的,更多用来代码演示和调试使用。

构造函数

javascript"> new THREE.MeshBasicMaterial(options)

属性讲解

  • color:材质的颜色,默认值为白色(0xffffff)。
  • wireframe:是否以线框模式显示,默认值为 false。

示例

javascript">// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建几何体
const geometry = new THREE.BoxGeometry();

// 创建 MeshBasicMaterial 材质
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });

// 创建网格对象
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

// 渲染循环
function animate() {
    requestAnimationFrame(animate);
    //旋转
    cube.rotation.x += 0.01;
    cube.rotation.y += 0.01;

    renderer.render(scene, camera);
}

animate();

请添加图片描述

2. MeshLambertMaterial(Lambert网格材质

MeshLambertMaterial 是一种基于 Lambert 光照模型的材质,它可以模拟出漫反射的效果,受光照影响,但不产生镜面反射。适合创建具有粗糙表面的物体,像石头、木材等

构造函数

javascript"> new THREE.MeshLambertMaterial(options)

属性讲解

  • color:材质的颜色,默认值为白色(0xffffff)。
  • emissive:自发光颜色,默认值为黑色(0x000000),即不发光。

示例

javascript">// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建几何体
const geometry = new THREE.BoxGeometry(1,1,1);

// 创建 MeshLambertMaterial 材质
const material = new THREE.MeshLambertMaterial({ color: 0x8844aa });

// 创建网格对象
const sphere = new THREE.Mesh(geometry, material);
scene.add(sphere);

// 添加光源
let light = new THREE.DirectionalLight(0xffffff,4);
light.position.set(2, 2, 2);
scene.add(light);


// 渲染循环
function animate() {
    requestAnimationFrame(animate);
    //旋转
    sphere.rotation.x += 0.01;
    sphere.rotation.y += 0.01;

    renderer.render(scene, camera);
}

animate();

请添加图片描述

3. MeshPhongMaterial(高光网格材质

MeshPhongMaterial 也是一种基于光照模型的材质,它在 MeshLambertMaterial 的基础上增加了镜面反射效果,可以模拟出有光泽的物体表面。适用于金属、玻璃等材质

构造函数

javascript"> new THREE.MeshPhongMaterial(options)

属性讲解

  • color:材质的颜色,默认值为白色(0xffffff)。
  • specular:镜面反射颜色,默认值为灰色(0x111111)。
  • shininess:光泽度,值越大,反射越集中,默认值为 30。

示例

javascript">// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建几何体
const geometry = new THREE.CylinderGeometry();

// 创建 MeshPhongMaterial 材质
const material = new THREE.MeshPhongMaterial({
    color: 0x0000ff,
    specular: 0xffffff, //反射颜色
    shininess: 100 //光泽度
});

// 创建网格对象
const cylinder = new THREE.Mesh(geometry, material);
scene.add(cylinder);

// 添加光源
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(1, 1, 1);
scene.add(light);

// 渲染循环
function animate() {
    requestAnimationFrame(animate);
      
    cylinder.rotation.x += 0.01;
    cylinder.rotation.y += 0.01;

    renderer.render(scene, camera);
}

animate();

请添加图片描述

4. MeshStandardMaterial(标准网格材质

MeshPhongMaterial 基于物理的渲染(PBR)材质,更准确地模拟真实世界中物体与光线的交互,考虑了漫反射、镜面反射、环境光遮蔽等因素,可创建逼真效果。它可以通过设置金属度和粗糙度属性来模拟不同的材质,从金属到非金属都能很好地表现。

构造函数

javascript"> new THREE.MeshStandardMaterial(options)

属性讲解

  • color:材质的颜色,默认值为白色(0xffffff)。
  • roughness:粗糙度,值越大,表面越粗糙,默认值为 1。
  • metalness:金属度,值越大,表面越像金属,默认值为 0。

示例

javascript">
// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建几何体
const geometry = new THREE.ConeGeometry();

// 创建 MeshStandardMaterial 材质
const material = new THREE.MeshStandardMaterial({
    color: 0xffff00,
    roughness: 0.5,//粗糙度
    metalness: 0.8//金属度
});

// 创建网格对象
const cylinder = new THREE.Mesh(geometry, material);
scene.add(cylinder);

// 添加光源
const light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(1, 1, 1);
scene.add(light);

// 渲染循环
function animate() {
    requestAnimationFrame(animate);
      
    cylinder.rotation.x += 0.01;
    cylinder.rotation.y += 0.01;

    renderer.render(scene, camera);
}

animate();

请添加图片描述

5. MeshPhysicalMaterial(物理网格材质

MeshPhysicalMaterial 是 Three.js 里基于物理渲染(PBR,Physically Based Rendering)的一种材质,它在 MeshStandardMaterial 的基础上进行了拓展,提供了更多的参数用于更精细地模拟真实世界中物体的外观和光学特性,从而创建出非常逼真的材质效果。如折射率、透明度等,适用于创建更复杂的材质效果,如液体、半透明物体等

构造函数

javascript"> new THREE.MeshPhysicalMaterial(options)

属性讲解

  • clearcoat:清漆层的强度,取值范围是 0 到 1。清漆层可以模拟物体表面的一层透明涂层,如汽车漆、家具表面的清漆等,增加物体表面的光泽感。
  • clearcoatRoughness:清漆层的粗糙程度,取值范围是 0 到 1。控制清漆层表面的光滑程度,影响清漆层反射的清晰度。
  • ior:折射率(Index of Refraction),取值范围通常在 1 到 2.33 之间。用于控制光线在材质内部折射的程度,不同的材质有不同的折射率,例如水的折射率约为 1.33,玻璃的折射率约为 1.5。
  • transmission:透明度(仅适用于透明材质),取值范围是 0 到 1。值为 0 时,材质完全不透明;值为 1 时,材质完全透明,可用于创建玻璃、水等透明物体。
  • specularIntensity:镜面反射强度,控制材质表面镜面反射的亮度。

示例

javascript">// 创建场景
const scene = new THREE.Scene();

// 创建相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
camera.position.z = 5;

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

// 创建几何体
const geometry = new THREE.SphereGeometry(1, 32, 32);

// 创建 MeshPhysicalMaterial 材质
const material = new THREE.MeshPhysicalMaterial({
  color: 0x00ffff,
  roughness: 0.1,//粗糙度
  metalness: 0.2,//金属度
  clearcoat: 0.8,//清漆层的强度
  clearcoatRoughness: 0.2,//清漆层的粗糙程度
  ior: 1.5,//折射率
  transmission: 0.5,//透明度
  specularIntensity: 0.8,//镜面反射强度
});

// 创建网格对象
const mesh = new THREE.Mesh(geometry, material);
scene.add(mesh);

// 添加光照
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);

const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);

// 渲染循环
function animate() {
  requestAnimationFrame(animate);

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

  renderer.render(scene, camera);
}

animate();

请添加图片描述


五、通用的材质属性

除了上述各个材质特有属性外,在 Three.js 中,许多材质类都继承自 THREE.Material 基类,因此具备一些通用的材质属性。下面介绍一些常用的通用材质属性。

属性名称类型说明默认值
colorTHREE.Color定义材质的基础颜色。可以使用十六进制值、CSS 颜色字符串或者 RGB 值来设置不同材质默认值不同,如 MeshBasicMaterial 默认是 new THREE.Color(0xffffff)(白色)
opacityNumber控制材质的不透明度,取值范围是从 0(完全透明)到 1(完全不透明)。不过,要使 opacity 生效,还需将 transparent 属性设置为 true1
transparentBoolean指示材质是否透明false
fogBoolean决定材质是否受场景中雾效的影响。如果设置为 false,则该材质不会被雾效所模糊或改变颜色true
receiveShadowBoolean指定材质是否接收阴影。如果要让物体表面显示其他物体投射的阴影,需将此属性设置为 true,同时渲染器的 shadowMap.enabled 也必须设置为 truefalse
castShadowBoolean表示材质是否投射阴影。设置为 true 后,该材质对应的物体在光照下会投射阴影到其他接收阴影的物体表面。false
sideNumber定义材质的渲染面。可选值有 THREE.FrontSide(只渲染正面)、THREE.BackSide(只渲染背面)和 THREE.DoubleSide(双面渲染)THREE.FrontSide
mapTHREE.Texture材质的纹理贴图,用于给物体表面添加纹理。可以通过加载图片来创建纹理并赋值给该属性null
wireframeBoolean是否以线框模式渲染物体。设置为 true 后,物体会以线框形式显示false
flatShadingBoolean是否使用平面着色。设为 true 会让物体表面以平面块的形式显示,产生硬边效果,常用于创建低多边形风格的模型false

示例:带透明六面不同颜色正方体

javascript">import * as THREE from "three";
//引入相机控制器
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

// 创建场景
const scene = new THREE.Scene();
 
// 创建坐标轴辅助器
 const axesHelper = new THREE.AxesHelper(40);
 scene.add(axesHelper);


// 创建相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
camera.position.z = 5;

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

 // 创建正方体的几何体
 const geometry = new THREE.BoxGeometry();

// 为正方体的每个面创建不同颜色的半透明材质
const materials = [
    new THREE.MeshLambertMaterial({ color: 0xff0000, transparent: true, opacity: 0.6 }), // 红色
    new THREE.MeshLambertMaterial({ color: 0x00ff00, transparent: true, opacity: 0.6 }), // 绿色
    new THREE.MeshLambertMaterial({ color: 0x0000ff, transparent: true, opacity: 0.6 }), // 蓝色
    new THREE.MeshLambertMaterial({ color: 0xffff00, transparent: true, opacity: 0.6 }), // 黄色
    new THREE.MeshLambertMaterial({ color: 0xff00ff, transparent: true, opacity: 0.6 }), // 紫色
    new THREE.MeshLambertMaterial({ color: 0x00ffff, transparent: true, opacity: 0.6 })  // 青色
];

// 创建网格对象,将几何体和材质数组传入
const mesh = new THREE.Mesh(geometry, materials);

scene.add(mesh);

// 添加光照
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);

let directionalLight = new THREE.DirectionalLight(0xffffff, 10);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);

directionalLight = new THREE.DirectionalLight(0xffffff, 10);
directionalLight.position.set(-1, -1, -1);
scene.add(directionalLight);


// 创建 OrbitControls 控件
const controls = new OrbitControls(camera, renderer.domElement);

// 设置阻尼(惯性),让控件的操作更平滑
controls.enableDamping = true;
controls.dampingFactor = 0.05;


// 渲染循环
function animate() {
  requestAnimationFrame(animate);

  mesh.rotation.x += 0.01;
  mesh.rotation.y += 0.01;
  controls.update();

  renderer.render(scene, camera);
}

animate();

请添加图片描述

通过生成6个不同颜色的材质对象组成数组传递给网格对象构造函数生成6个不同颜色面的立方体

六、 材质的高级应用

纹理映射:除了使用纯色,我们还可以通过纹理(Texture)来为材质添加更丰富的细节。纹理可以是图片、法线贴图、凹凸贴图等。例如,使用 TextureLoader 加载一张图片作为纹理,并应用到 MeshBasicMaterial 上:

核心代码:

javascript">//加载纹理
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load('texture.jpg');
//创建立方体
const geometry = new THREE.BoxGeometry(1, 1, 1);
//创建材质
const material = new THREE.MeshBasicMaterial({ map: texture });
// 创建网格对象,将几何体和材质传入
const mesh= new THREE.Mesh(geometry, material);
scene.add(mesh);

示例:纹理贴图——自转的地球

javascript">import * as THREE from "three";
//引入相机控制器
import { OrbitControls } from "three/addons/controls/OrbitControls.js";

// 创建场景
const scene = new THREE.Scene();
 
// 创建相机
const camera = new THREE.PerspectiveCamera(
  75,
  window.innerWidth / window.innerHeight,
  0.1,
  1000
);
camera.position.z = 5;

// 创建渲染器
const renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

 // 创建正方体的几何体
 const geometry = new THREE.SphereGeometry(1, 32, 32);

 // 加载纹理
 const textureLoader = new THREE.TextureLoader();
 const texture = textureLoader.load('https://pic1.zhimg.com/v2-4f5bc4b2185ff9a57993bca60e6adc90_r.jpg');

// 创建材质并应用纹理
const material =new THREE.MeshLambertMaterial({ map: texture })

// 创建网格对象,将几何体和材质传入
const mesh = new THREE.Mesh(geometry, material);

scene.add(mesh);

// 添加环境光
const ambientLight = new THREE.AmbientLight(0x404040);
scene.add(ambientLight);
// 添加平行光
let directionalLight = new THREE.DirectionalLight(0xffffff, 10);
directionalLight.position.set(1, 1, 1);
scene.add(directionalLight);
// 添加平行光2
directionalLight = new THREE.DirectionalLight(0xffffff, 10);
directionalLight.position.set(-1, -1, -1);
scene.add(directionalLight);


// 创建 OrbitControls 控件
const controls = new OrbitControls(camera, renderer.domElement);

// 设置阻尼(惯性),让控件的操作更平滑
controls.enableDamping = true;
controls.dampingFactor = 0.05;


// 渲染循环
function animate() {
  requestAnimationFrame(animate);


  mesh.rotation.y += 0.01;
  controls.update();

  renderer.render(scene, camera);
}

animate();

请添加图片描述

上述代码中我们新建了一个球体几何体和新建一个基础材质并设置纹理属性,纹理对象加载了地球图片,最终呈现一个自转的3D地球效果


五、总结

       通过本文的介绍,我们对 Three.js 中的材质有了更深入的了解。从基础的 MeshBasicMaterial 到基于物理的 MeshStandardMaterial 和 MeshPhysicalMaterial,以及材质的高级应用,这些知识将帮助我们创建出更加逼真和富有表现力的 3D 场景。在实际开发中,我们需要根据具体的需求选择合适的材质类型,并不断调整材质的属性,以达到最佳的视觉效果。

更多three.js入门知识点请关注该系列教程后续的更新。


http://www.niftyadmin.cn/n/5865779.html

相关文章

流媒体网络协议全解析:从实时传输到自适应流,如何选择最优方案?

一、历史发展与协议提出者 流媒体协议的发展与互联网技术迭代紧密相关,主要分为三个阶段: 早期专有协议(1990s-2000s) RTSP/RTP 提出者:RealNetworks(RTSP初始推动者),后由IETF标准化(RFC 2326)。背景:1996年推出,用于视频监控和点播系统,基于UDP传输媒体流,支持…

详解golang的Gengine规则引擎

一:简介 Gengine是一款基于golang和AST(抽象语法树)开发的规则引擎, Gengine支持的语法是一种自定义的DSL, Gengine通过内置的解释器对规则文件进行解析,构建规则模型,进行相应的规则计算和数据处理。Gengine于2020年7月由哔哩哔哩(bilibili.com)授权开源。Gengine现已应用…

前端学习—HTML

前端学习 html概括 HTML结构标签定义网页内容 CSS样式配置,规定网页布局 JavaScript编程网页行为 HTML超文本标记语言,是一套标记标签,描述网页的 XHTML是以XML格式编写的HTML HTML文档也叫web页面,由互相嵌套的HTML元素构…

机试题——新能源汽车充电桩建设策略

题目描述 随着新能源汽车的蓬勃发展,新能源汽车充电桩的覆盖密度越来越重要。某汽车公司建设充电桩的思路如下: 一条高速沿线,每个区域建设一个充电站,充电站内有多个充电桩,充电站之间保持合理的距离。每个充电站可…

C#开发——ConcurrentDictionary集合

ConcurrentDictionary<TKey, TValue> 是 C# 中一个专为多线程场景设计的线程安全字典集合&#xff0c;位于 System.Collections.Concurrent 命名空间中。它允许多个线程同时对字典进行读写操作&#xff0c;而无需额外的同步措施。 一、集合特征 此集合有如下特征…

LabVIEW新能源客车CAN监控软件

LabVIEW平台开发的新能源客车监控软件&#xff0c;提高客车下线调试及售后服务的效率和质量。该软件通过实时数据监控和故障诊断功能&#xff0c;为技术人员提供了强大的数据支持&#xff0c;使得车辆问题可以迅速被识别和解决。 ​ 项目背景 随着新能源客车市场的快速发展&a…

《Keras 3 :使用 Vision Transformers 进行物体检测》:此文为AI自动翻译

《Keras 3 :使用 Vision Transformers 进行物体检测》 作者:Karan V. Dave 创建日期:2022 年 3 月 27 日最后修改时间:2023 年 11 月 20 日描述:使用 Vision Transformer 进行对象检测的简单 Keras 实现。 (i) 此示例使用 Keras 3 在 Colab 中查看 GitHub 源 介绍 A…

Helix——Figure 02发布的通用人形机器人控制VLA:不用微调即可做多个任务的快与慢双系统,让两个机器人协作干活(含清华HiRT详解)

前言 过去一周&#xff0c;我花了很大的心思、力气&#xff0c;把deepseek的GRPO、MLA算法的代码解析通透&#xff0c;比如GRPO与PPO的详细对比&#xff0c;再比如MLA中&#xff0c;图片 公式 代码的一一对应&#xff0c;详见此专栏《火爆全球的DeepSeek系列模型》 2.20日晚&…