写在前面
在Three.js中,灯光是为了让3D场景更加真实和逼真而存在的。灯光可以用来模拟现实中的光照效果,例如阴影、反射和折射等。在本文中,我们将介绍Three.js中的不同类型的灯光,以及如何在场景中添加和调整它们的属性。
1 基础介绍
1 点光源
点光源是一种从一个点向四面八方发射光线的灯光,类似于普通的灯泡或者蜡烛。点光源可以用来模拟现实中的局部光照效果,
例如现实中的手电筒或者灯泡所产生的光照效果。
在Three.js中,可以通过创建THREE.PointLight对象来创建一个点光源。
var light = new THREE.PointLight(0xffffff, 1, 100); light.position.set(0, 0, 0); scene.add(light);
上面的代码创建了一个白色的点光源,强度为1,范围为100。我们将其位置设置为(0,0,0),也就是场景的中心点。在场景中添加了点光源之后,场景中的物体就会受到点光源的照射,产生局部的光照效果。
2 平行光源
平行光源是一种从一个方向上发射光线的灯光,类似于太阳的光线。平行光源可以用来模拟现实中的全局光照效果,例如现实中的太阳或者天空所产生的光照效果。
在Three.js中,我们可以通过创建THREE.DirectionalLight对象来创建一个平行光源。
var light = new THREE.DirectionalLight(0xffffff, 1); light.position.set(0, 1, 0); scene.add(light);
上面的代码创建了一个白色的平行光源,强度为1。我们将其位置设置为(0,1,0),也就是在场景正上方。在场景中添加了平行光源之后,场景中的物体就会受到平行光源的照射,产生全局的光照效果。
3 聚光灯
聚光灯是一种从一个点向一个方向发射光线的灯光,类似于手电筒或者车灯。聚光灯可以用来模拟现实中的局部光照效果,例如现实中的手电筒或者车灯所产生的光照效果。
在Three.js中,我们可以通过创建THREE.SpotLight对象来创建一个聚光灯。
var light = new THREE.SpotLight(0xffffff, 1, 100, Math.PI/4, 1); light.position.set(0, 0, 0); light.target.position.set(0, -1, 0); scene.add(light); scene.add(light.target);
上面的代码创建了一个白色的聚光灯,强度为1,范围为100。我们将其位置设置为(0,0,0),也就是场景的中心点。我们还设置了聚光灯的方向和角度,以及聚光灯的目标位置。在场景中添加了聚光灯之后,场景中的物体就会受到聚光灯的照射,产生局部的光照效果。
4 调整灯光属性
在Three.js中,我们可以通过修改灯光的属性来调整灯光的光照效果。例如,我们可以修改灯光的颜色、强度、范围、方向、角度等属性来改变灯光的光照效果。以下是一些常见的灯光属性:
color:
color:设置灯光的颜色,可以使用十六进制颜色值或者THREE.Color对象。
例如:
light.color = new THREE.Color(0xff0000);
intensity:
intensity:设置灯光的强度,值为0-1之间的浮点数。例如:
light.intensity = 0.5;
distance:
distance:设置灯光的范围,即灯光照射的最远距离。例如:
light.distance = 200;
position
position:设置灯光的位置。例如:
light.position.set(0, 0, 0);
target:
target:设置聚光灯的目标位置。例如:
light.target.position.set(0, -1, 0);
angle:
angle:设置聚光灯的角度,即灯光照射的范围。例如:
light.angle = Math.PI / 4;
penumbra:
penumbra:设置聚光灯的软边缘,即灯光照射的边缘部分的柔和程度。例如:
light.penumbra = 0.5;
通过修改灯光的属性,我们可以调整灯光的光照效果,使场景更加真实和逼真。
总结
上面介绍了在Three.js中创建不同类型的灯光,包括点光源、平行光源和聚光灯,并演示了如何在场景中添加和调整它们的属性。
通过使用灯光,可以为场景添加逼真的光照效果,使场景更加生动和真实。
在实际的项目中,可以根据需要选择不同类型的灯光,并根据具体场景调整灯光的属性,以达到最佳的效果。
2 示例介绍
这里提供一个使用多个灯光的Three.js场景示例,让你可以更好地理解和应用灯光。
HTML部分
<!DOCTYPE html> <html> <head> <title>Three.js Lighting Example</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script> <style> body { margin: 0; overflow: hidden; } canvas { display: block; } </style> </head> <body>
这是HTML部分,我们先来看一下页面的头部。在头部中,我们引入了Three.js库的核心文件
three.min.js
,以及一个标题和一些元数据,以及一些样式。
2.2 JavaScript部分
创建一个场景
<script> // 创建一个场景 var scene = new THREE.Scene();
创建透视相机
我们使用Three.js创建一个场景,场景将会存放所有的物体、灯光和相机。
// 创建一个透视相机 var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 ); camera.position.z = 5;
WebGL渲染
接着,我们创建一个透视相机。这个相机有四个参数,分别是视角、宽高比、近剪切面和远剪切面。在这个例子中,我们将视角设置为75度,宽高比设置为浏览器窗口的宽高比,近剪切面设置为0.1,远剪切面设置为1000。我们也设置了相机的位置,将其放在z轴5个单位的位置上。
// 创建一个WebGL渲染器 var renderer = new THREE.WebGLRenderer(); renderer.setSize( window.innerWidth, window.innerHeight ); document.body.appendChild( renderer.domElement );
然后,我们创建一个WebGL渲染器,并将其添加到页面中。
setSize()
方法设置了渲染器的大小,将其设置为浏览器窗口的大小。document.body.appendChild()
方法将渲染器的DOM元素添加到了页面中,这样我们就可以在页面上看到场景了。// 创建一个盒子网格模型并将其添加到场景中 var geometry = new THREE.BoxGeometry(); var material = new THREE.MeshPhongMaterial( { color: 0x00ff00 } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube );
创建盒子模型
接下来,我们创建了一个盒子网格模型,并将其添加到场景中。在这里,我们使用了
BoxGeometry
和MeshPhongMaterial
两个类来创建盒子的形状和材质,并将它们传递给Mesh
类的构造函数来创建一个网格模型。scene.add()
方法将模型添加到场景中。// 创建一个球体网格模型并将其添加到场景中 var geometry2 = new THREE.SphereGeometry(1.5, 32, 32); var material2 = new THREE.MeshPhongMaterial( { color: 0xff0000 } ); var sphere = new THREE.Mesh( geometry2, material2 ); sphere.position.x = 2.5; scene.add( sphere );
我们也创建了一个球体网格模型,并将其添加到场景中。这里我们使用了
SphereGeometry
和MeshPhongMaterial
两个类来创建球体的形状和材质,并将它们传递给Mesh
类的构造函数来创建一个网格模型。我们还设置了球体的位置,将其放在x轴2.5个单位的位置上。// 添加点光源 var pointLight = new THREE.PointLight( 0xffffff, 1, 100 ); pointLight.position.set( 0, 0, 0 ); scene.add( pointLight ); pointLight.distance = 50; pointLight.intensity = 2;
现在,我们添加了一个点光源。在这里,我们使用
PointLight
类来创建一个点光源,并将其位置设置为(0, 0, 0)。我们还设置了光源的距离和强度。// 添加平行光源 var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.7 ); directionalLight.position.set( 0, 1, 0 ); scene.add( directionalLight ); directionalLight.color = new THREE.Color(0xffe5b4);
接着,我们添加了一个平行光源。在这里,我们使用
DirectionalLight
类来创建一个平行光源,并将其位置设置为(0, 1, 0)。我们还设置了光源的颜色。// 添加聚光灯 var spotLight = new THREE.SpotLight( 0xffffff, 1, 100, Math.PI/4, 1 ); spotLight.position.set( 0, 2, 0 ); spotLight.target.position.set( 0, 0, 0 ); scene.add( spotLight ); scene.add( spotLight.target ); spotLight.color = new THREE.Color(0xffc0cb); spotLight.distance = 50; spotLight
添加聚光灯
// 添加聚光灯
var spotLight = new THREE.SpotLight( 0xffffff, 1, 100, Math.PI/4, 1 );
spotLight.position.set( 0, 2, 0 );
spotLight.target.position.set( 0, 0, 0 );
scene.add( spotLight );
scene.add( spotLight.target );
spotLight.color = new THREE.Color(0xffc0cb);
spotLight.distance = 50;
spotLight.intensity = 2;
spotLight.angle = Math.PI/6;
spotLight.penumbra = 0.2;
渲染场景
我们还添加了一个聚光灯。在这里,我们使用
SpotLight
类来创建一个聚光灯,并设置了它的位置和目标。我们还设置了光源的距离、颜色、强度、角度和半影。// 渲染场景 function animate() { requestAnimationFrame( animate ); cube.rotation.x += 0.01; cube.rotation.y += 0.01; sphere.rotation.x += 0.01; sphere.rotation.y += 0.01; renderer.render( scene, camera ); } animate();
最后,定义了一个
animate
函数,用于渲染场景。在这个函数中,我们使用了requestAnimationFrame
方法来递归地调用animate
函数,实现了每一帧的渲染。在渲染之前,我们还对盒子和球体进行了旋转,并调用了renderer.render
方法来渲染场景。
2.3 完整代码
完整代码如下
<!DOCTYPE html>
<html>
<head>
<title>Three.js Lighting Example</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/r128/three.min.js"></script>
<style>
body {
margin: 0;
overflow: hidden;
background-color: black; /* 将背景色设置为黑色 */
}
canvas {
display: block;
}
</style>
</head>
<body>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
camera.position.z = 5;
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
var geometry = new THREE.BoxGeometry();
var material = new THREE.MeshPhongMaterial( { color: 0x00ff00 } );
var cube = new THREE.Mesh( geometry, material );
scene.add( cube );
var geometry2 = new THREE.SphereGeometry(1.5, 32, 32);
var material2 = new THREE.MeshPhongMaterial( { color: 0xff0000 } );
var sphere = new THREE.Mesh( geometry2, material2 );
sphere.position.x = 2.5;
scene.add( sphere );
// 添加点光源
var pointLight = new THREE.PointLight( 0xffffff, 1, 100 );
pointLight.position.set( 0, 0, 0 );
scene.add( pointLight );
pointLight.distance = 50;
pointLight.intensity = 2;
// 添加平行光源
var directionalLight = new THREE.DirectionalLight( 0xffffff, 0.7 );
directionalLight.position.set( 0, 1, 0 );
scene.add( directionalLight );
directionalLight.color = new THREE.Color(0xffe5b4);
// 添加聚光灯
var spotLight = new THREE.SpotLight( 0xffffff, 1, 100, Math.PI/4, 1 );
spotLight.position.set( 0, 2, 0 );
spotLight.target.position.set( 0, 0, 0 );
scene.add( spotLight );
scene.add( spotLight.target );
spotLight.color = new THREE.Color(0xffc0cb);
spotLight.distance = 50;
spotLight.intensity = 2;
spotLight.angle = Math.PI/6;
spotLight.penumbra = 0.2;
// 渲染场景
function animate() {
requestAnimationFrame( animate );
cube.rotation.x += 0.01;
cube.rotation.y += 0.01;
sphere.rotation.x += 0.01;
sphere.rotation.y += 0.01;
renderer.render( scene, camera );
}
animate();
</script>
</body>
</html>
你可以在浏览器中运行这段代码,就可以看到一个拥有三种不同类型灯光的场景。你可以尝试调整灯光的属性,以获得不同的效果。
这个示例可以帮助你更好地理解和应用灯光,同时也为你提供了一个灵感,可以在你的项目中应用类似的场景和效果。