第3章
學習使用Three.js中的光源
在第1章中,我們學習了Three.js的基礎知識,而在上一章,我們對場景中最重要的部分進行了一些深入的了解,包括幾何體、網格和錄影機。你可能已經注意到,盡管燈光也是場景中十分重要的一部分,但是在之前的章節中卻略過了。沒有光源,渲染的場景将不可見(除非你使用基礎材質或線框材質)。Three.js中包含大量的光源,每一個光源都有特别的用法,是以我們會用一整章來闡述不同光源的詳情,并為下一章材質的使用做準備。
WebGL本身并不支援光源。如果不使用Three.js,則需要自己寫WebGL着色程式來模拟光源。查閱使用WebGL從頭開始模拟光源的推薦資料請通路如下網址:
https://developer.mozilla.org/en-US/docs/Web/WebGL/Lighting_in_WebGL。
在本章中你将學到以下幾個主題:
- Three.js中可用的光源。
- 特定光源使用的時機。
- 如何調整和配置所有光源的行為。
- 簡單地介紹如何建立鏡頭光暈。
在本書所有的章節中,有大量的示例可以用來試驗光源的行為。本章的示例代碼可以在提供的源碼的chapter-03檔案夾中找到。
3.1 Three.js中不同種類的光源
Three.js中有許多不同種類的光源,每種光源都有特别的行為和用法。在本章中,将讨論表3.1中所列光源。

本章主要分為兩部分内容。首先,我們先看一下基礎光源:THREE.AmbientLight、 THREE.PointLight、THREE.SpotLight和THREE.DirectionalLight。所有這些光源都是基于THREE.Light 對象擴充的,這個對象提供公用的功能。以上提到的光源都是簡單光源,隻需一些簡單的配置即可,而且可用于建立大多數場景的光源。在第二部分,我們将會看到一些特殊用途的光源和效果:THREE.HemisphereLight、THREE.AreaLight和THREE.LensFlare。隻有在十分特殊的情況下才會用到這些光源。
3.2 基礎光源
我們将從最基本的THREE.AmbientLight光源開始。
3.2.1 THREE.AmbientLight
在建立THREE.AmbientLight時,顔色将會應用到全局。該光源并沒有特别的來源方向,并且THREE.AmbientLight不會生成陰影。通常,不能将THREE.AmbientLight作為場景中唯一的光源,因為它會将場景中的所有物體渲染為相同的顔色,而不管是什麼形狀。在使用其他光源(如THREE.SpotLight或THREE.DirectionalLight)的同時使用它,目的是弱化陰影或給場景添加一些額外的顔色。了解這點的最簡單方式就是檢視chapter-03檔案夾下的例子01-ambient-light.html。在這個例子裡,可以使用一個簡單的使用者界面來修改添加到場景中的THREE.AmbientLight光源。請注意,在這個場景中,也使用了THREE.SpotLight光源來照亮物體并生成陰影。
從如圖3.1所示的截圖裡,你可以看到我們使用了第1章中的場景,并且THREE.AmbientLight的顔色和強度是可調的。在這個例子中,可以關閉聚光燈來檢視隻有THREE.AmbientLight光源的效果。
我們在這個場景中使用的标準顔色是#606008。這是該顔色的十六進制表示形式。前兩個值表示顔色的紅色部分,緊接着的兩個值表示綠色部分,而最後兩個值表示藍色部分。在該例的使用者界面中顯示的是顔色的十進制值。
在這個例子裡,我們使用一個非常暗淡的灰色,用來弱化網格對象在地面上生硬的投影。通過右上角的菜單,你可以将這個顔色改成比較明顯的黃橙色:rgb(190,190,41),這樣所有對象就會籠罩在類似陽光的光輝下,如圖3.2所示。
正如圖3.2所示,這個黃橙色應用到了所有的對象,并在整個場景中投下了一片橙色的光輝。使用這種光源時要記住:用色應該盡量保守。如果你指定的顔色過于明亮,那麼你很快就會發現畫面的顔色過于飽和了。除了顔色之外,還可以為環境光設定強度值。這一參數決定了光源THREE.AmbientLight對場景中物體顔色的影響程度。如果将該參數調小,則光源對顔色的影響會很微弱。如果将該值調大,則整個場景會變得過于明亮。實際效果如圖3.3所示。
既然我們已經知道了THREE.AmbientLight光源能做什麼,接下來學習如何建立和使用THREE.AmbientLight光源。下面幾行代碼展示了如何建立THREE.AmbientLight光源,以及如何将該光源與我們前幾章已見過的GUI控制菜單關聯起來。
建立THREE.AmbientLight光源非常簡單。由于THREE.AmbientLight光源不需要指定位置并且會應用到全局,是以隻需使用new THREE.AmbientLight("#606008")來指定顔色(十六進制),并用scene.add(ambientLight)将此光源應用到整個場景。環境光類的構造函數還有一個可選參數intensity,用于指定光的強度。上面的代碼并沒有指定強度值,則該值使用預設值1。在這個例子裡,将THREE.AmbientLight光源的顔色和強度綁定到控制菜單。為此,可以使用與前面章節相同的配置方法。唯一需要改變的是調用gui.addColor(…)函數而不是gui.add(…)函數。該方法會在控制菜單裡添加一個選項,在這個選項裡可以直接改變傳入的顔色變量。在代碼中,你可以看到我們使用了dat.GUI控制菜單的onChange功能:gui.addColor(…).onChange(function(e){…})。通過這個函數,我們告訴dat.GUI控制菜單在每次顔色改變的時候調用傳入的函數。對于本例來講,我們會在這個函數裡将THREE.AmbientLight光源的顔色設定為一個新值。最後我們通過類似方法確定控制菜單中intensity選項的任何修改都會作用于場景中的環境光對象。
使用THREE.Color對象
在講述下一個光源之前,我們先簡單介紹一下THREE.Color對象。在Three.js中需要(例如為材質、燈光等)指定顔色時,可以使用THREE.Color對象,也可以像我們在設定環境光時所做的那樣,以一個字元串指定顔色。此時Three.js将基于該字元串自動建立一個THREE.Color對象。實際上Three,js在構造THREE.Color對象時非常靈活,它可以基于下面所列的任何一種方式來完成:
- 無參數構造:new THREE.Color()這種構造形式會建立一個代表白顔色的對象。
- 十六進制數值:new THREE.Color(0xababab)這種構造形式會将十六進制值轉換為顔色分量值并基于此構造顔色對象。這是最佳的顔色對象構造形式。
- 十六進制字元串:new THREE.Color("#ababab"),此時Three.js會将字元串當作CSS顔色字元串去解釋,并構造顔色對象。
- RGB字元串:顧名思義,這種構造形式需要為每個RGB分量指定亮度值,其具體形式可以是new THREE.Color("rgb(255, 0, 0)")或者new THREE.Color("rgb(100%, 0%, 0%)")。
- 顔色名稱:可以使用Three.js能夠識别的顔色名稱字元串,例如new THREE.Color("skyblue")。
- HSL字元串:如果相比RGB,你更熟悉HSL色域,也可以使用HSL值來構造顔色對象,例如new THREE.Color("hsl(0%, 100%, 50%)")。
- 分離的RGB值:最後也可以直接使用RGB顔色分量來構造顔色對象。這三個值的範圍都是0到1。形式例如new THREE.Color(1, 0, 0)。
如果需要修改一個現有顔色對象的顔色,可以用新顔色值構造一個臨時顔色對象,并将其複制給現有對象。另一種修改顔色的方式是使用THREE.Color類攜帶的方法來讀取和修改其内部顔色值,如表3.2所列。
從這張表中可以看出,要改變目前顔色有很多方法。其中很多是Three.js庫内部使用的,但同樣也提供了一些方法輕松修改光源和材質的顔色。
在進入對THREE.PointLight、THREE.SpotLight和THREE.DirectionalLight的讨論之前,我們先看一下它們之間最主要的差別,那就是它們發射光線的方式。圖3.4展示了這三種光源如何發射光線。
從這個圖中可以看到如下資訊:
- THREE.PointLight從特定的一點向所有方向發射光線。
- THREE.SpotLight從特定的一點以錐形發射光線。
- THREE.DirectionalLight不是從單個點發射光線,而是從二維平面發射光線,光線彼此平行。
在接下來的幾節裡,我們将更詳細地介紹這些光源。
3.2.2 THREE.SpotLight
THREE.SpotLight(聚光燈光源)是最常使用的光源之一(特别是如果你想要使用陰影的話)。THREE.SpotLight是一種具有錐形效果的光源。你可以把它與手電筒或燈塔産生的光進行對比。該光源産生的光具有方向和角度。圖3.5展示了聚光燈光源的效果(02-spot-light.html)。
表3.3列出了适用于THREE.SpotLight的所有屬性。我們會先研究那些與光照直接相關的屬性,之後再看一看與渲染陰影有關的屬性。
當THREE.SpotLight的shadow屬性為enable時,可以通過表3.4中的屬性來調節陰影特性。
建立聚光燈光源非常簡單。隻要指定顔色、設定想要的屬性并将其添加到場景中即可,如下代碼所示:
在上面代碼中,我們建立了THREE.SpotLight對象執行個體,并且将castShadow屬性設定為true,因為我們想要陰影。此外,由于需要讓這個光源照向指定的方向,是以我們通過設定target屬性來實作。在本例中,我們将其指向名為plane的對象。當運作示例(02-spot-light.html)時,你将看到如圖3.6所示的場景。
在這個例子裡,可以設定一些THREE.SpotLight對象獨有的屬性。其中之一就是target屬性。如果我們對藍色球體(sphere對象)設定此屬性,那麼這個光源會一直瞄準球體的中心,即使它在繞場景移動。我們建立這個光源時,瞄準的是地面(plane)對象,而在我們的例子中,也可以将光源瞄準另外兩個物體。但是如果你不想把光源瞄準一個特定的對象,而是空間中的任意一點呢?可以通過建立一個THREE.Object3D()對象來實作,如下代碼所示:
然後,設定THREE.SpotLight對象的target屬性:
在表3.3中列出了幾個适用于THREE.SpotLight的屬性,這些屬性可以控制光線如何從THREE.SpotLight對象發出。distance屬性和angle屬性定義了光錐的形狀。angle屬性定義了光錐的角度,而distance屬性則可以用來設定光錐的長度。圖3.7解釋了這兩個值如何一起定義了從THREE.SpotLight對象發出光線的區域。
通常情況是不需要設定這些值的,因為它們的預設值比較合适,但是也可以使用這些屬性,例如建立一個光柱很窄或光強遞減很快的THREE.SpotLight對象。此外,還有最後一個可以更改THREE.SpotLight光源渲染方式的屬性—penumbra屬性。通過這個屬性,可以設定光強從光錐中心向錐形邊緣遞減的速度。在圖3.8中,可以看到penumbra屬性的運作結果—一束非常明亮的光(intensity值很高),離中心越遠光強衰減得越快(penumbra值很高)。
在開始學習下一個光源之前,我們先簡要介紹一下THREE.SpotLight光源提供的幾個與陰影相關的屬性。我們已經學過,将THREE.SpotLight對象的castShadow屬性設定為true可以生成陰影。(當然,在場景中渲染THREE.Mesh對象時,要確定為要投射陰影的對象設定castShadow屬性,為要顯示陰影的對象設定receiveShadow屬性。)Three.js庫也允許對陰影渲染的方式進行微調。這些已經在表3.3中進行了介紹。通過shadow.camara.near、shadow.camera.far和shadow.camera.fov,可以控制光線如何投射陰影和在哪裡投射陰影。其工作原理與我們前面章節中講的透視錄影機的工作原理是一緻的。想看看這些是如何起作用的,最簡單的方法添加THREE.CameraHelper。在示例程式中可以通過勾選菜單上的shadowDebug(陰影調試)複選框來設定。這樣可以把用來決定陰影的光照區域顯示出來,如圖3.9所示。
當實際陰影效果與所希望的不一緻時,使用THREE.CameraHelper可以非常友善地幫助我們發現問題所在。下面代碼展示了如何使用THREE.CameraHelper。
與調試陰影類似,如果你需要調試聚光燈光源本身存在的問題,可以使用Three,js提供的THREE.SpotLightHelper,并通過下面代碼所示的方法使用該類。
在THREE.SpotLightHelper的幫助下,我們可以直覺地看到聚光燈的形狀和朝向,如圖3.10所示。
下面針對使用陰影的過程中可能遇到的問題給出幾個提示:
- 如果陰影看上去有點粗糙(如陰影形狀的邊緣呈塊狀),可以增加shadow.mapSize.width和shadow.mapSize.height屬性的值,或者保證用于計算陰影的區域緊密包圍在對象周圍。可以通過shadow.camera.near、shadow.camera.far和shadow.camera.fov屬性來配置這個區域。
- 記住,不僅要告訴光源生成陰影,而且還必須通過配置每個幾何體的castShadow和receiveShadow屬性來告訴幾何體對象是否接收或投射陰影。
- 如果你在場景中使用薄對象,在渲染陰影時,可能會出現奇怪的渲染失真現象。通常可以使用shadow.bias屬性輕微偏移陰影來修複這些問題。
- 如果想要陰影更柔和,可以在THREE.WebGLRenderer對象上設定不同的shadowMap- Type屬性值。預設情況下,此屬性的值為THREE.PCFShadowMap;如果将此屬性設定為PCFSoftShadowMap,則會得到更柔和的陰影。
3.2.3 THREE.PointLight
Three.js庫中的THREE.PointLight(點光源)是一種單點發光、照射所有方向的光源。夜空中的照明彈就是一個很好的點光源的例子。與所有光源一樣,我們有一個專門的例子,你可以通過這個例子來試驗THREE.PointLight。打開chapter-03檔案夾下的03-point-light.html,你會看到一個點光源繞場景移動的例子。如圖3.11所示。
本例中的場景還是第1章的那個場景,隻是這次有一個點光源繞場景移動。為了更清楚地看到這個點光源在哪裡,我們讓一個橙色的小球(sphere對象)沿着相同的軌迹移動。随着光源的移動,你将看到紅色的方塊和藍色的球被這個光源從不同的側面照亮。
如果你使用過舊版Three.js便會知道點光源(THREE.PointLight)不會産生陰影,然後在新版Three.js中,點光源也可以像聚光燈(THREE.SpotLight)和平行光(THREE.DirectionalLight)一樣産生陰影了。
用THREE.PointLight可以對光源設定很多額外的屬性,具體見表3.5。
點光源可以像聚光燈光源一樣啟用陰影并設定其屬性。在接下來的幾個例子和截圖中,我們将解釋這些屬性。首先,我們先看看如何建立THREE
我們使用指定的顔色建立了一個光源(這裡使用了一個字元串值,也可以使用一個數字或THREE.Color對象),設定了它的position(位置)和distance(距離)屬性,并将它添加到場景中。在介紹聚光燈光源時,我們曾在示例代碼中設定了intensity和distance屬性,這些屬性對點光源同樣有效。效果如圖3.12所示。
示例代碼中沒有設定power(功率)和decay(衰減)這兩個屬性,但它們對于模拟真實世界很有意義。下面網站為這兩個屬性的使用提供了很好的示例程式:
https://threejs.org/examples/#webgl_lights_physical。在前面介紹聚光燈光源時,已經展示了使用intensity屬性的效果,該屬性對點光源同樣适用,并能産生類似效果,如圖3.13所示。
此外,聚光燈光源的distance屬性在點光源上也能産生相似效果。下面的圖3.14示範了當光的intensity值很高而distance值卻很小時所産生的光源效果。
聚光燈光源中的distance屬性決定了在光線強度變為0之前光線的傳播距離。在圖3.14中,光線強度在距離為14的地方慢慢地減少為0。這就是為什麼在這個例子中你仍然可以看到一個被照亮的明亮區域,但光卻不會把更遠的地方照亮。distance屬性的預設值為0,這意味着光線強度不會随着距離的增加而減弱。
THREE.PointLight同樣使用錄影機來決定如何繪制陰影,是以也可以使用輔助類THREE.CameraHelper來展示場景中哪些部分被光源的錄影機所覆寫,以及使用輔助類THREE.PointLightHelper來展示點光源的光線所照射的位置。兩個輔助類一起使用時,我們 便可以獲得非常直覺的調試資訊,如圖3.15所示。
3.2.4 THREE.DirectionalLight
我們要看的最後一個基本光源是THREE.DirectionalLight(平行光)。這種類型的光可以看作是距離很遠的光。它發出的所有光線都是互相平行的。平行光的一個範例就是太陽光。太陽是如此遙遠,以至于到達地球時所有的光線(幾乎)都是互相平行的。THREE.DirectionalLight和我們之前看過的THREE.SpotLight之間的主要差別是:平行光不像聚光燈(可以通過distance和exponent屬性來微調)那樣離目标越遠越暗淡。被平行光照亮的整個區域接收到的光強是一樣的。
可以在示例04-directional-light.html中看到實際效果,如圖3.16所示。
從上圖可以看到,場景裡沒有那種錐形效果的光線。所有對象接收的都是相同光強的光。隻有光源的方向(direction)、顔色(color)和強度(intensity)屬性用來計算顔色和陰影。
與THREE.SpotLight一樣,可以設定一些屬性來控制光照的強度和投射陰影的方式。THREE.DirectionalLight對象和THREE.SpotLight對象有許多屬性相同,例如position、target、intensity、castShadow、shadow.camera.near、shadow.camera.far、shadow.mapSize.width、shadow.mapSize.height和shadow.bias。關于這些屬性更多的資訊,可以檢視3.2.3節。下面隻讨論平行光光源特有的幾個屬性。
如果你研究一下THREE.SpotLight的例子,會發現我們必須定義生成陰影的光錐。然而,對于THREE.DirectionalLight,由于所有的光線都是平行的,是以不會有光錐,而是一個立方體區域,如圖3.17所示(如果想看到它,可以移動錄影機遠離場景并勾選debug複選框)。
在這個立方體範圍内的所有對象都可以投影和接收陰影。與THREE.SpotLight一樣,包圍對象的空間定義得越緊密,投影的效果越好。可以使用下面幾個屬性來定義這個立方體範圍:
可以把這個與第2章中配置正交投影錄影機的方法比較一下。
3.3 特殊光源
這一節講述的是特殊光源,我們将讨論Three.js提供的兩個特殊光源。首先要讨論的是THREE.HemisphereLight(半球光光源),這種光源可以為戶外場景建立更加自然的光照效果。然後我們會看一看THREE.AreaLight(區域光光源),它可以從一個很大的區域發射光線,而不是從單個點。最後,會展示一下如何在場景中添加鏡頭光暈的效果。
3.3.1 THREE.HemisphereLight
第一個特殊光源是THREE.HemisphereLight。使用THREE.Hemisphere Light,可以建立出更加貼近自然的戶外光照效果。如果不使用這個燈光,要模拟戶外光照,可以建立一個THREE.DirectionalLight來模拟太陽光,并且可能再添加一個THREE.AmbientLight來為場景提供基礎色。但是,這樣的光照效果看起來并不怎麼自然。在戶外,并不是所有的光照都來自上方:很多是來自于大氣的散射和地面以及其他物體的反射。Three.js中的THREE.HemisphereLight光源就是為這種情形建立的。它為獲得更自然的戶外光照效果提供了一種簡單的方式。關于它的示例,可以檢視示例05-hemisphere-light.html,截圖如圖3.18所示。
注意這是第一個需要加載額外的資源,并且不能從本地的檔案系統直接運作的例子。是以,如果你還沒有這樣做,可以參考第1章,了解如何建立一個本地的Web伺服器,或者禁用浏覽器中的安全設定,使之可以加載外部資源。
仔細觀察藍色球體可以發現,該球體表面的底部有接近草地的綠色,而頂部有接近天空的藍色(通過設定color屬性獲得)。在這個示例中,可以打開或關閉THREE.HemisphereLight,也可以設定顔色和光強。建立一個半球光光源就像建立其他光源一樣簡單:
你隻需要給它指定接收來自天空的顔色,接收來自地面的顔色,以及這些光線的光照強度。之後如果想修改這些屬性值,可以使用表3.6所列出的屬性。
3.3.2 THREE.AreaLight
我們最後要看的光源是THREE.AreaLight。使用THREE.AreaLight,可以定義一個長方形的發光區域。在舊版Three.js中,THREE.AreaLight并不在标準的Three.js庫中,而是在它的擴充庫中,是以在使用之前我們要完成幾個額外的步驟。而在新版Three.js中則可以直接使用THREE.AreaLight。在深入細節之前先來看一下我們追求的結果(打開06-area-light.html示例),如圖3.19所示。
從截圖中可以看到,我們定義了三個THREE.AreaLight對象,每個都有自己的顔色,你也可以看到這些光源是如何影響整個區域的。要使用THREE.AreaLight光源,需要先在HTML檔案的head标簽中添加如下導入庫:
添加了上述導入庫後,便可以像添加其他光源一樣來添加THREE.AreaLight光源:
在這個示例裡,建立了一個新的THREE.AreaLight對象。這個光源的顔色為0xff0000,光強的值為500,width就4,height是10。與其他光源一樣,可以使用position屬性設定該光源在場景中的位置。在建立THREE.AreaLight時,會建立出一個垂直平面。在這個示例中,建立了三個THREE.AreaLight對象,有不同的顔色。當你第一次嘗試該光源的時候,可能會覺得奇怪:為什麼在你放置光源的地方什麼都看不到?這是因為你不能看到光源本身,而隻能看到它發射出的光,而且隻有當這些光照射到某個物體上時才能看到。如果你想建立出例子中所展示的場景,可以在相同的位置(areaLight1.position)增加THREE.PlaneGeometry或THREE.BoxGeometry對象來模拟光線照射的區域,代碼如下所示:
通過THREE.AreaLight可以建立出非常漂亮的效果,但是可能要多試驗才能獲得想要的效果。拉下右上角的控制台,會找到一些控件來設定場景中三個光源的顔色和光強,并立即看到設定後的效果,如圖3.20所示。
3.3.3 鏡頭光暈
本章将要讨論的最後一個主題是鏡頭光暈(lens flare)。你可能已經對鏡頭光暈很熟悉了。例如,當你直接朝着太陽或另一個非常明亮的光源拍照時就會出現鏡頭光暈效果。在大多數情況下,需要避免出現這種情形,但是對于遊戲和三維圖像來說,它提供了一種很好的效果,讓場景看上去更加真實。
Three.js庫也支援鏡頭光暈,而且在場景中添加它非常簡單。在最後這一節中,我們将在場景中添加一個鏡頭光暈,并建立出如圖3.21所示的效果。可以打開示例檔案07-lensflares.html來檢視這個效果。
可以通過執行個體化THREE.LensFlare對象來建立鏡頭光暈。首先要做的是建立這個對象。THREE.LensFlare對象接受如下參數:
這些參數的含義在表3.7中列出。
我們看看建立這個對象的代碼(請見示例07-lensflares.html):
首先需要加載一個紋理。在這個示例裡,我使用的是Three.js示例庫中的鏡頭光暈紋理,如圖3.22所示。
如果将這張圖與圖3.21展示的截圖相比較,會發現它定義了鏡頭光暈的樣子。接下來,使用“new THREE.Color(0xffacc);”定義鏡頭光暈的顔色,這将使鏡頭光暈泛着紅光。有了這兩個對象之後,就可以建立THREE.LensFlare對象了。在這個示例裡,把光暈的尺寸設定為350,距離設定為0.0(就在光源處)。
建立完LensFlare對象之後,将它放在光源處,添加到場景中,如圖3.23所示。
這看起來已經很好了,但是如果把這張截圖與圖3.21相比較,你會發現在頁面中央少了一些小的圓形失真圖形。
我們會使用與建立主光暈相同的方法來建立它們,如下代碼所示:
但是這次并沒有建立一個新的THREE.LensFlare,而是使用了剛建立的THREE.LensFlare對象的add方法。在這個方法中,隻需指定紋理(texture)、尺寸(size)、距離(distance)和混合(blending)模式。
注意add方法可以接受兩個額外的參數。在add方法中,你還可以給新光暈設定顔色(color)和不透明度(opacity)屬性。這些新光暈使用的紋理是一個顔色很淡的圓,在目錄assets/textures/flares/下可以找到本示例所使用的光暈圖檔。
如果你再來看這個場景,就會發現失真圖形出現在用distance參數指定的位置。
3.4 總結
本章涵蓋了Three.js庫中提供的各種不同燈源,資訊量非常大。在本章中,我們學習了配置光源、顔色和陰影,并且知道了它們不是嚴謹的科學。要獲得正确的結果,需要不斷試驗,使用dat.GUI控件可以微調配置。不同的光源以不同的方式表現,正如第4章将介紹的,材質也會對光源有不同的反應。THREE.AmbientLight光源的顔色可以附加到場景中的每一種顔色上,通常用來柔化生硬的顔色和陰影。THREE.PointLight光源會朝所有方向發射光線,不能被用來建立陰影。THREE.SpotLight光源類似于手電筒。它有一個錐形的光束,可以配置它随着距離的增大而逐漸變弱,并且可以生成陰影。我們還學習了THREE.DirectionalLight光源。這個光源相當于遠光的效果,比如太陽光。它的光線彼此平行,其光強并不會随着與目标對象距離的增大而減弱。除了這些标準光源之外,我們還學習了幾個更加特殊的光源。如果想要一個更加自然的戶外效果,可以使用THREE.HemisphereLight光源,它考慮了天空和地面的反射。THREE.AreaLight不從單個點發射光線,而是從一個很大的區域發射光線。我們還展示了如何通過THREE.LensFlare對象添加圖像化的鏡頭光暈。
到本章為止,我們已經介紹了幾種不同的材質。在本章,你也看到了各種材質對于光照的反應各不相同。下一章将會概述Three.js庫中的各種材質。