【Three.js】第十五章 Lights 灯

15. Lights 灯

介绍

正如我们在上一课中看到的,添加灯光就像添加网格一样简单。您使用适当的类实例化一盏灯,然后将其添加到场景中。
有多种类型的光,我们已经发现了AmbientLightPointLight
在本课中,我们将详细了解所有不同的类以及如何使用它们。

设置

启动器中已经设置了一个场景(包括一个球体、一个立方体、一个环面和一个作为地板的平面),但如果您想自己写代码渲染联系,请自行创建项目尝试。
因为我们要使用灯光,所以我们必须使用对灯光有反应的材料。我们本可以使用MeshLambertMaterialMeshPhongMaterialMeshToonMaterial,但我们将使用 MeshStandardMaterial因为它是我们在上一课中看到的最真实的材料。材质还减少了roughness值0.4,去查看灯光的反射。

一旦启动器开始工作,从头开始我们移除AmbientLightPointLight两个光源。你应该得到一个渲染结果:纯黑色的幕布,里面什么都看不到。

环境光 AmbientLight

AmbientLight在场景的所有几何体上应用全向照明第一个参数是color,第二个参数是intensity。至于材质,可以在实例化时直接设置属性,也可以在实例化后更改:

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

// Equals
const ambientLight = new THREE.AmbientLight()
ambientLight.color = new THREE.Color(0xffffff)
ambientLight.intensity = 0.5
scene.add(ambientLight)


就像我们课程中对材料所做的操作那样,您可以将属性添加到调试 UI。我们不会在本课的其余部分调试新的属性,但如果您想简化测试,请随时添加调整:

gui.add(ambientLight, 'intensity').min(0).max(1).step(0.001)

如果您只有一个AmbientLight,您将获得与MeshBasicMaterial相同的效果,因为几何体的所有面都将被均匀照亮。
在现实生活中,当你照亮一个物体时,由于光线会在墙壁和其他物体上反射,因此与光相对的物体的侧面不会完全变黑。出于性能原因,Three.js 不支持光反射,但您可以使用昏暗的AmbientLight来伪造这种光反射。

定向光 DirectionalLight

DirectionalLight将具有类似太阳的效果就好像太阳光线平行传播一样。第一个参数是color,第二个参数是intensity

const directionalLight = new THREE.DirectionalLight(0x00fffc, 0.3)
scene.add(directionalLight)


默认情况下,光线似乎来自上方。position要更改它,您必须像使用普通对象一样使用该属性移动整个灯光。

directionalLight.position.set(1, 0.25, 0)


光的距离暂时无关紧要。光线来自无限空间,平行于无限对面传播。

半球光 HemisphereLight

HemisphereLightAmbientLight相似但天空的颜色与地面的颜色不同。面向天空的面将被一种颜色照亮,而另一种颜色的光将照亮面向地面的面。
第一个参数是color对应天空的颜色,第二个参数是groundColor对应地面的颜色,第三个参数是intensity

const hemisphereLight = new THREE.HemisphereLight(0xff0000, 0x0000ff, 0.3)
scene.add(hemisphereLight)

点光源 PointLight

PointLight几乎就像一个打火机光源无限小,光向各个方向均匀传播。第一个参数是color,第二个参数是intensity

const pointLight = new THREE.PointLight(0xff9000, 0.5)
scene.add(pointLight)


我们可以像移动任何对象一样移动它:

pointLight.position.set(1, - 0.5, 1)


默认情况下,光强度不会衰减。但是您可以使用distancedecay属性控制淡入淡出距离以及淡入淡出的速度。写入实例化类参数的第三个和第四个参数,或者在实例的属性中:

const pointLight = new THREE.PointLight(0xff9000, 0.5, 10, 2)

矩形区域光 RectAreaLight

RectAreaLight工作方式类似于您在照片拍摄集中看到的大矩形灯。它是定向光和漫射光之间的混合。第一个参数是color,第二个参数是intensity,第三个参数是矩形的width,第四个参数是它的height

const rectAreaLight = new THREE.RectAreaLight(0x4e00ff, 2, 1, 1)
scene.add(rectAreaLight)


RectAreaLight仅适用MeshStandardMaterialMeshPhysicalMaterial 。
然后您可以移动灯光并旋转它。为了简化旋转,您可以使用我们在上一课中看到的方法lookAt(...)

rectAreaLight.position.set(- 1.5, 0, 1.5)
rectAreaLight.lookAt(new THREE.Vector3())


没有任何参数的 Vector3,将具有它的xyz0(场景的中心)。

聚光灯 SpotLight

SpotLight就像手电筒一样工作它是一个从一点开始并朝向一个方向的光锥。这里是它的参数列表:

  • color: 颜色
  • intensity:强度
  • distance:强度下降到的距离0
  • angle: 光束有多大
  • penumbra:光束轮廓的扩散程度
  • decay:光线变暗的速度
const spotLight = new THREE.SpotLight(0x78ff00, 0.5, 10, Math.PI * 0.1, 0.25, 1)
spotLight.position.set(0, 2, 3)
scene.add(spotLight)


旋转我们的SpotLight有点困难。该实例有一个名为 target 的属性,它是一个Object3D。SpotLight始终注视着target那个对象。但是如果你试图改变它的位置,SpotLight不会移动:

spotLight.target.position.x = - 0.75


那是因为我们target不在现场。简单地添加target到场景中,它应该可以工作:

scene.add(spotLight.target)

表现

添加灯光后效果很棒,如果使用得当,可以使项目很逼真。问题是,就性能而言,灯光可能会花费很多性能。GPU 将不得不做很多计算,比如面部到光线的距离、面部面向光线的距离、面部是否在聚光灯锥中等。
尝试添加尽可能少的灯,并尝试使用成本较低的灯。
最低成本

  • 环境光
  • 半球光

中等成本

  • 定向光
  • 点光源

成本高:

  • 聚光灯
  • 矩形区域光

烘烤 Baking

一种很好的照明技术称为烘焙。这个想法是将光线烘焙到纹理中。这可以在 3D 软件中完成。不幸的是,您将无法移动灯光,因为没有灯光,而且您可能需要很多纹理。
一个很好的例子是Three.js Journey主页

帮手

定位和定向灯很困难。为了帮助我们,我们可以使用助手。现在只仅支持以下助手:

要使用它们,只需实例化这些类。使用相应的灯光作为参数,并将它们添加到场景中。第二个参数使您能够更改助手的size

const hemisphereLightHelper = new THREE.HemisphereLightHelper(hemisphereLight, 0.2)
scene.add(hemisphereLightHelper)

const directionalLightHelper = new THREE.DirectionalLightHelper(directionalLight, 0.2)
scene.add(directionalLightHelper)

const pointLightHelper = new THREE.PointLightHelper(pointLight, 0.2)
scene.add(pointLightHelper)

const spotLightHelper = new THREE.SpotLightHelper(spotLight)
scene.add(spotLightHelper)


RectAreaLightHelper有点难用现在,该类不是THREE核心变量的一部分。examples您必须像我们对OrbitControls所做的那样从依赖项中导入它:

import {
    
     RectAreaLightHelper } from 'three/examples/jsm/helpers/RectAreaLightHelper.js'

然后你可以使用它:

const rectAreaLightHelper = new RectAreaLightHelper(rectAreaLight)
scene.add(rectAreaLightHelper)

猜你喜欢

转载自blog.csdn.net/m0_68324632/article/details/131152003
今日推荐