Skip to content

添加光源

1.基本使用

如下有个立方体

js
const scene = new THREE.Scene()

const camera = new THREE.PerspectiveCamera(45, 800 / 500, 1, 2000)
camera.position.set(0, 0, 20)

const renderer = new THREE.WebGLRenderer({
    antialias: true,
})
renderer.setSize(800, 500)
document.body.append(renderer.domElement)

const cubeGeometry = new THREE.BoxGeometry(5, 5, 5)
const cubeMaterial = new THREE.MeshBasicMaterial({
    color: 0x00ffff,
})
const cube = new THREE.Mesh(cubeGeometry, cubeMaterial)
scene.add(cube)

const controls = new OrbitControls(camera, renderer.domElement)
controls.addEventListener('change', () => {
    renderer.render(scene, camera)
})
renderer.render(scene, camera)

const animation = () => {
    requestAnimationFrame(animation)
    cube.rotation.y -= 0.01
    renderer.render(scene, camera)
}
animation()

PixPin_2024-10-17_14-05-08

添加一个点光源

js
const pointLight = new THREE.PointLight(0xffffff, 1.0)
pointLight.position.set(6,6,6)
pointLight.intensity = 1000000 //光照强度
scene.add(pointLight)

发现并没有卵用

是因为MeshBasicMaterial材质不会受光照影响

我们换成可受光照影响的MeshPhongMaterial材质

js
// const cubeMaterial = new THREE.MeshBasicMaterial({
//     color: 0x00ffff,
// })

const cubeMaterial = new THREE.MeshPhongMaterial({
    color: 0x00ffff,
})

PixPin_2024-10-17_14-10-10

发现哪里不正常

这是因为,只有被点光源照射到的面才会显示出来,点光源照不到的面都是黑的

想要解决这个问题,我们需要添加一个环境光

js
const ambientLight = new THREE.AmbientLight(0xffffff, 0.5)
scene.add(ambientLight)

PixPin_2024-10-17_14-12-38

2.受光照影响的材质

threejs提供的网格材质,有的受光照影响,有的不受光照影响。

  • 受光照影响的材质,被光照到的一面会更亮一些,反面会暗一些
  • 不受光照影响的材质,每一面颜色都是一样的

image-20241011142700176

3.光源种类

Three.js提供了多种模拟生活中光源的API,

image-20241011142824032

其中不同光源的效果如下

image-20241011142914363

3.1 点光源

点光源PointLight可以类比为一个发光点,就像生活中一个灯泡以灯泡为中心向四周发射光线。

js
//点光源:两个参数分别表示光源颜色和光照强度
// 参数1:0xffffff是纯白光,表示光源颜色
// 参数2:1.0,表示光照强度,可以根据需要调整
const pointLight = new THREE.PointLight(0xffffff, 1.0);

除了通过THREE.PointLight的参数2设置光照强度,你可以可以直接访问光照强度属性intensity设置。

javascript
pointLight.intensity = 1.0;//光照强度

如图,被光照到的一面颜色更亮一些,而反面会暗一些

image-20241011144745163

把点光源想象为一个电灯泡,你在3D空间中,放的位置不同,模型的渲染效果就不一样。

注意光源位置尺寸大小:如果你希望光源照在模型的外表面,那你就需要把光源放在模型的外面。

js
//点光源位置
pointLight.position.set(400, 0, 0);//点光源放在x轴上

光源和网格模型Mesh对应一样是三维场景的一部分,自然需要添加到三维场景中才能起作用。

js
scene.add(pointLight); //点光源添加到场景中

最后,添加光源整体代码如下

js
const pointLight = new THREE.PointLight(0xffffff, 1) 
pointLight.position.set(3,3,3)
scene.add(pointLight)

3.2 环境光

通过THREE.AmbientLight创建一个环境光,环境光没有特定的方向,只是整体改变场景的光照明暗。

js
//环境光:没有特定方向,整体改变场景的光照明暗
const ambient = new THREE.AmbientLight(0xffffff, 0.4);
scene.add(ambient);

3.3 平行光

通过THREE.DirectionalLight创建一个平行光

js
// 平行光
const directionalLight = new THREE.DirectionalLight(0xffffff, 1);
// 设置光源的方向:通过光源position属性和目标指向对象的position属性计算
directionalLight.position.set(80, 100, 50);
// 方向光指向对象网格模型mesh,可以不设置,默认的位置是0,0,0
directionalLight.target = mesh;
scene.add(directionalLight);

平行光辅助观察DirectionalLightHelper

js
// DirectionalLightHelper:可视化平行光
const dirLightHelper = new THREE.DirectionalLightHelper(directionalLight, 5,0xff0000);
scene.add(dirLightHelper);

4.光源衰减

实际生活中点光源,比如比如一个灯泡,随机距离的改变,光线会衰减,越来越弱,光源衰减属性.decay默认值是2.0,如果你不希望衰减可以设置为0.0

javascript
pointLight.decay = 0.0;//设置光源不随距离衰减

【扩展提醒】:如果使用默认衰减2.0,不同版本可能有差异,对于部分threejs新版本,有时候你可能看不到光源效果,这时候可以把光照强度加强试试看,如果你的版本不影响,就不用加强光照强度(根据版本情况灵活对应)。

javascript
// 你可以对比不同光照强度明暗差异(传播同样距离)
pointLight.intensity = 10000.0;//光照强度
pointLight.intensity = 50000.0;//光照强度

5.虚拟光源

光源我们是看不到的,但可以创建一个虚拟光源让我们观察光源的位置

通过THREE.PointLightHelper可以创建一个虚拟点光源

js
const pointLight = new THREE.PointLight( 0xff0000, 1, 100 );
pointLight.position.set( 10, 10, 10 );
scene.add( pointLight );

const pointLightHelper = new THREE.PointLightHelper( pointLight,0 );	// 点光源的对象,和虚拟光源大小
scene.add( pointLightHelper );

虚拟点光源的效果如下

image-20241011144334885

MIT Licensed