本文目录
前言
在Three.js中,灯光(Lights)是构建逼真3D场景的重要组成部分,它们能够模拟现实世界中的光照效果,如阴影、反射和折射等,从而增强场景的真实感和立体感。
一、演示代码准备
1.1 代码
我们先在场景下添加三个物体及地面,编写代码如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
html,
body {
margin: 0;
padding: 0;
width: 100%;
height: 100%;
}
</style>
</head>
<body>
<script type="module">
// 倒入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'
import * as THREE from "three";
// 创建场景
const scene = new THREE.Scene();
// 创建相机
const camera = new THREE.PerspectiveCamera( // 透视相机
45, // 视角 角度数
window.innerWidth / window.innerHeight, // 宽高比 占据屏幕
0.1, // 近平面(相机最近能看到物体)
1000, // 远平面(相机最远能看到物体)
);
camera.position.set(0, 2, 11);
// camera.lookAt(0, 0, 0);
// 创建渲染器
const renderer = new THREE.WebGLRenderer({
antialias: true, // 抗锯齿
});
// 设置渲染器宽高
renderer.setSize(window.innerWidth, window.innerHeight)
// renderer(渲染器)的dom元素添加到我们的HTML文档中
document.body.appendChild(renderer.domElement)
// 物体
const plane = new THREE.Mesh(
new THREE.PlaneGeometry(10, 10),
new THREE.MeshStandardMaterial()
)
plane.rotation.x = -Math.PI / 2
const cube = new THREE.Mesh(
new THREE.BoxGeometry(2,2,2),
new THREE.MeshStandardMaterial()
)
cube.position.set(0,2,0)
const sphere = new THREE.Mesh(
new THREE.SphereGeometry(1,32,32),
new THREE.MeshStandardMaterial()
)
sphere.position.set(3,2,0)
const geometry = new THREE.ConeGeometry( 1, 4, 6 );
const material = new THREE.MeshStandardMaterial();
const cone = new THREE.Mesh( geometry, material );
cone.position.set(-3,3,0)
scene.add(plane, cube, sphere, cone );
// 控制器
const control = new OrbitControls(camera, renderer.domElement)
// 开启阻尼惯性,默认值为0.05
control.enableDamping = true
// 渲染循环动画
function animate() {
// 在这里我们创建了一个使渲染器能够在每次屏幕刷新时对场景进行绘制的循环(在大多数屏幕上,刷新率一般是60次/秒)
requestAnimationFrame(animate);
// 更新控制器。如果没在动画里加上,那必须在摄像机的变换发生任何手动改变后调用
control.update();
renderer.render(scene, camera);
};
// 执行动画
animate();
</script>
</body>
</html>
1.2 效果
可以看到场景中物体及地面都是黑的因为我们要演示灯光就用了MeshStandardMaterial
材质,这种材质受光照影响。没有光照就一片黑。
二、AmbientLight
2.1 简要介绍
- 描述:环境光是全局光源,均匀地照亮场景中的所有物体,环境光不能用来投射阴影,因为它没有方向。
- 用途:用于提供场景的基础照明,通常与其他光源配合使用,以避免场景过于黑暗。
- 属性:主要包括颜色(
color
)和强度(intensity
)。
2.2 代码
基于以上代码,再加入环境光代码如下:
const light = new THREE.AmbientLight( 0x404040 ); // 柔和的白光
scene.add( light );
2.3 效果
效果如下:
可以看到环境光不管从哪个视角看都是一样的。
三、DirectionalLight
3.1 简要介绍
- 描述:平行光从特定方向投射,类似于太阳光,所有光线是平行的,可以产生阴影。
- 用途:用于模拟太阳光或其他远距离光源,适合用于户外场景。
- 属性:除了颜色和强度外,还包括位置(
position
)和目标位置(target
用于确定光的方向)。
3.2 代码
删掉AmbientLight
环境光后再加入如下代码:
// 从上方照射的白色平行光,强度为 1
const directionalLight = new THREE.DirectionalLight( 0xffffff, 1);
directionalLight.position.set(0,5,0)
scene.add( directionalLight );
3.3 效果
可以看到默认从y
轴投下来的光。
3.4 辅助器
那么我们平行光有辅助器,加入代码如下:
const helper = new THREE.DirectionalLightHelper( directionalLight, 5 );
scene.add( helper );
可以看到,辅助器显示从上往下照射:
3.5 改变光源方法
那么我们还可以改变光源方向,代码如下:
directionalLight.position.set(5,5,0)
效果如下:
四、HemisphereLight
4.1 简要介绍
- 描述:半球光有两个颜色,一个是天光(上方),一个是地光(下方),没有阴影。
- 用途:用于提供柔和的全局光照效果,适合用于户外场景,模拟天空和地面的光照。
- 属性:主要包括天空的颜色(
skyColor
)和地面的颜色(groundColor
),以及强度。
4.2 代码
由于圆锥展示效果不如圆环,我们将圆锥物体删除后加入圆环物体:
const geometry = new THREE.TorusGeometry( 1, 0.5, 20, 25 );
const material = new THREE.MeshStandardMaterial();
const torus = new THREE.Mesh( geometry, material );
torus.position.set(-3,2,0)
然后删掉之前光照后再加入如下代码:
const light = new THREE.HemisphereLight( 0xff0000, 0x0000ff, 1 );
scene.add( light );
4.3 效果
可以看到从上往下看,和从下往上看光颜色的不同。
五、PointLight
5.1 简要介绍
构造器(
Constructor
)
PointLight( color : Color, intensity : Float, distance : Number, decay : Float )
color
-(可选)一个表示颜色的Color
的实例、字符串或数字,默认为一个白色(0xffffff
)的Color
对象。
intensity
-(可选)光照强度。默认值为 1。
distance
- 光源照射的最大距离。默认值为 0(无限远)。
decay
- 沿着光照距离的衰退量。默认值为 2。
- 描述:点光源从一个点向所有方向发光,类似于灯泡,可以产生阴影。
- 用途:用于模拟近距离的光源,例如灯泡、蜡烛等。
- 属性:包括颜色、强度、距离(
distance
,光源照射的最远距离)和衰减(decay
,光线强度随距离变化的速率)。
5.2 代码
删掉之前光照后再加入如下代码:
const light = new THREE.PointLight( 0xff0000, 1, 100 );
scene.add( light );
5.3 效果
可以看到光源默认在原点。
5.4 辅助器
那么我们点光源有辅助器,加入代码如下:
const pointLightHelper = new THREE.PointLightHelper( light, 1 );
scene.add( pointLightHelper );
可以看到:
5.5 改变光源方向
写入如下代码:
light.position.set(0,5,0);
效果如下:
六、更多灯光
在学习的路上,如果你觉得本文对你有所帮助的话,那就请关注点赞评论三连吧,谢谢,你的肯定是我写博的另一个支持。