Threejs 材质贴图、光照和投影详解

1. 材质和贴图

材质(Material)定义了物体表面的外观,包括颜色、光泽度、透明度等。贴图(Textures)是应用于材质的图像,它们可以增加物体表面的细节和真实感。

1.1材质类型

  • **MeshBasicMaterial:**不受光照影响的基础材质。
  • **MeshLambertMaterial:**考虑漫反射的材质,适合简单的光照场景。
  • **MeshPhongMaterial:**考虑镜面高光的材质,适合光滑表面的物体。
  • **MeshStandardMaterial:**基于物理的材质,支持金属度和粗糙度贴图,适用于现代渲染管线。
  • **MeshPhysicalMaterial:**类似MeshStandardMaterial,但提供更高级的基于物理的渲染特性。

1.2 贴图的作用

  • map(颜色贴图):定义物体的基本颜色。
  • normalMap(法线贴图):通过模拟表面的微小凹凸来增加细节,不增加几何复杂度。
  • aoMap(环境光贴图):模拟物体表面因邻近物体遮挡而产生的暗部效果。
  • displacementMap(位移贴图):实际改变几何形状,创建真实的物理凹凸效果。
  • roughnessMap(粗糙度贴图):控制材质的金属性质和表面粗糙度。
javascript 复制代码
// 贴图
let textureLoader = new THREE.TextureLoader();
let floor = textureLoader.load("./images/base.jpg");
let ambient = textureLoader.load("./images/ambient.jpg");
let height = textureLoader.load("./images/height.jpg");
let normal = textureLoader.load("./images/normal.jpg");
let roughness = textureLoader.load("./images/roughness.jpg");

// 创建一个平面物体
let plane = new THREE.Mesh(
  new THREE.PlaneGeometry(10, 10),
  new THREE.MeshStandardMaterial({
    map: floor, // 基础纹理贴图
    aoMap:ambient, // 环境光贴图
    displacementMap:height, // 位移贴图
    normalMap:normal, // 法线贴图
    roughnessMap:roughness,  // 粗糙度贴图

  }),
);

1.3 效果如下

2. 光照

光照是通过添加光源来实现的,光源类型包括:

  • 环境光(AmbientLight):提供全局照明效果,均匀照亮场景中的所有物体,不会产生阴影。

  • 平行光(DirectionalLight):模拟无限远的光源,如太阳,光线平行,不受距离影响。

  • 点光源(PointLight):从一个点向所有方向发出光线,光线强度随着距离增加而衰减。

  • 半球光(HemisphereLight) :光源直接放置于场景之上,光照颜色从天空光线颜色渐变到地面光线颜色。

  • 聚光灯(SpotLight):具有特定方向和圆锥形照射范围的光源,可以产生软边缘或硬边缘的阴影。

javascript 复制代码
// 1. 环境光:均匀的照亮场景中的所有物体。
const ambientLight = new THREE.AmbientLight(0xff0000);
// scene.add( helper );

// 2. 平行光:沿着特定方向发射的光。
const directionalLight = new THREE.DirectionalLight(0x00ffff, 1);
directionalLight.position.set(0, 5, 0)
// 平行光辅助对象
const directionalLighthelper = new THREE.DirectionalLightHelper( directionalLight, 1 );
// scene.add( helper );

// 3. 半球光:光源直接放置于场景之上,光照颜色从天空光线颜色渐变到地面光线颜色。
const hemisphereLight = new THREE.HemisphereLight( 0xff0000, 0x00ff00, 1 );
// scene.add( hemisphereLight );
// 半球光辅助对象
const hemisphereLighthelper = new THREE.HemisphereLightHelper( hemisphereLight, 1 );
// scene.add( hemisphereLighthelper );

// 4. 点光源:从一个点向各个方向发射的光源。
const pointLight = new THREE.PointLight( 0xff0000, 1, 100 ); // 第二个参数1是光照强度,第三个参数100是光源的衰减距离
scene.add( pointLight );
// 点光源辅助对象
const pointLightHelper = new THREE.PointLightHelper( pointLight, 1 );
scene.add( pointLightHelper );

3. 投影

投影需要确保渲染器和光源都支持阴影,并设置物体的castShadowreceiveShadow 属性。阴影的质量可以通过调整光源的shadow.mapSize和其他阴影参数来优化。

javascript 复制代码
// 投影: 光源  物体  渲染器

// 平行光:沿着特定方向发射的光。
const directionalLight = new THREE.DirectionalLight(0x00ffff, 1);
directionalLight.position.set(5, 5, 0)
scene.add(directionalLight);
// 平行光辅助对象
const directionalLighthelper = new THREE.DirectionalLightHelper(directionalLight, 1);
scene.add(directionalLighthelper);

// 创建一个平面物体
let plane = new THREE.Mesh(
  new THREE.PlaneGeometry(10, 10),
  new THREE.MeshStandardMaterial({ color: 0xffffff })
);
plane.rotation.x = -Math.PI / 2;

// 创建一个立方体物体
let cube = new THREE.Mesh(
  new THREE.BoxGeometry(2, 2, 2),
  new THREE.MeshStandardMaterial()
);
cube.position.set(0, 2, 0)


// 1.开启渲染器,支持投影
renderer.shadowMap.enabled = true;
// 2.物体开启阴影
cube.castShadow = true;
// 3.接收阴影的物体
plane.receiveShadow = true;
// 4.光照开启阴影
directionalLight.castShadow = true;
// 5.阴影分辨率
directionalLight.shadow.mapSize.width = 2048;
directionalLight.shadow.mapSize.height = 2048;
相关推荐
ZwaterZ2 分钟前
vue el-table表格点击某行触发事件&&操作栏点击和row-click冲突问题
前端·vue.js·elementui·c#·vue
西凉河的葛三叔7 分钟前
vue3+elementui-plus el-dialog全局配置点击空白处不关闭弹窗
前端·vue3·elementui-plus
周三有雨14 分钟前
【面试题系列Vue07】Vuex是什么?使用Vuex的好处有哪些?
前端·vue.js·面试·typescript
木古古1827 分钟前
使用chrome 访问虚拟机Apache2 的默认页面,出现了ERR_ADDRESS_UNREACHABLE这个鸟问题
前端·chrome·apache
爱米的前端小笔记36 分钟前
前端八股自学笔记分享—页面布局(二)
前端·笔记·学习·面试·求职招聘
loey_ln1 小时前
webpack配置和打包性能优化
前端·webpack·性能优化
建群新人小猿1 小时前
会员等级经验问题
android·开发语言·前端·javascript·php
爱上语文1 小时前
HTML和CSS 表单、表格练习
前端·css·html
djk88881 小时前
Layui Table 行号
前端·javascript·layui