深入理解three.js中平面光光源RectAreaLight

  • 2019 年 10 月 3 日
  • 筆記

前言

之前有深入講解過Three.js中光源,在那篇文章的最後也說了由於平面光光源的特殊性,所以會單獨拿出來講解,這篇文章會詳細的講解平面光光源的特性和實際應用該如何使用。

首先,平面光光源從一個矩形平面上均勻地發射光線,這種光源的主要應用場景是模擬明亮的窗戶或者條狀燈光光源,實際在開發傢具建模項目中會有廣泛應用。平面光光源的最大特點事不支持陰影,我們無法通過設置RectAreaLight.castShadow = true來映射讓物體顯示陰影,而且,平面光光源支持的材質也很有限,只有MeshStandardMaterialMeshPhysicalMaterial兩種材質。有一點需要特別說明下,查看官方文檔中有 你必須在你的場景中加入 RectAreaLightUniformsLib ,並調用init() 注意事項,但是我在項目中使用發現,我不添加RectAreaLightUniformsLib也是能夠正常運行的

原理說明

創建一個平面光光源很簡單,官網實例如下:

 1 var width = 10;   2 var height = 10;   3 var intensity = 1;   4 var rectLight = new THREE.RectAreaLight( 0xffffff, intensity,  width, height );   5 rectLight.position.set( 5, 5, 0 );   6 rectLight.lookAt( 0, 0, 0 );   7 scene.add( rectLight )   8 rectLightHelper = new THREE.RectAreaLightHelper( rectLight );   9 scene.add( rectLightHelper );

new THREE.RectAreaLight用於創建平面光光源構造器函數,該函數有四個變量,分別是colorintensitywidthheight,以上四個參數都是可選參數,如果不傳都會按照默認的值來創建平面光光源。

color:(可選參數) 十六進制數字表示的光照顏色,缺省值為 0xffffff (白色),實測中發現使用HEX格式和RGB格式都是可以的,但是RGBA格式不支持。

intensity:(可選參數) 光源強度/亮度 ,缺省值為 1,實測最小值為0,最大值不限,2為自然光亮度。

width:(可選參數) 光源寬度,缺省值為 10,只要不小於0都可以。

height:(可選參數) 光源高度,缺省值為 10,只要不小於0都可以。

rectLight.position.set( 5, 5, 0 ) 這行代碼用來指示平面光光源位置,這個位置可以隨意設定,只要在camera設定的範圍內都可以,如果超出了我們將什麼都看不到,當然這個位置最好離映射物體不能太遠,因為本身平面光光源模擬的是窗口光,所有它的輻射距離很有限,位置設定離物體太遠將無法映射物體。

rectLight.lookAt( 0, 0, 0 )這行代碼用來指代平行光光源指向的中心位置,一般情況下會指向需要映射物體的中心位置。

rectLightHelper = new THREE.RectAreaLightHelper( rectLight )這行代碼再次說明下,實測中刪掉也是可以正常執行的。

應用場景說明

首先,需要說明,Three.js中的所有光源在場景中是沒有任何顯示的,我們是感知不到光源的,所以為了模擬現實中的光源點,比如太陽、燈泡等,我們一般會通過創建一個材質為MeshBasicMaterial的物體來替代現實中的光源。至於為什麼會選擇MeshBasicMaterial的材質來替代光源,後續我會專門寫一篇博文來詳細講解MeshBasicMaterial這種材質。回到平面光光源,項目中模擬平面光光源通常會通過面板來指代光源,一般使用的比較多的是平面緩衝幾何體PlaneBufferGeometry。

平面緩衝幾何體替代平面光光源位置的時候,我們需要創建兩個平面緩衝幾何體,這樣做是為了保證我們看到平面光光源指向的是同一個方向。

平面光光源正面平面緩衝幾何體代碼如下:

1 var rectLightMesh = new THREE.Mesh( new THREE.PlaneBufferGeometry(), new THREE.MeshBasicMaterial( {color:'#ffffff' side: THREE.BackSide } ) );  2 rectLightMesh.scale.x = rectLight.width;  3 rectLightMesh.scale.y = rectLight.height;  4 rectLight.add( rectLightMesh );

上述代碼中,rectLight表示已經創建好的平面光光源,rectLightMesh 表示平面光光源正面的平面緩衝幾何體,正面的平面緩衝幾何體我們一定要設置智能單面查看,必須設置side = THREE.BackSide,這樣做是為了保證方面的平面緩衝幾何體能夠上色。

平面光光源反面平面緩衝幾何體代碼如下:

1 var rectLightMeshBack = new THREE.Mesh( new THREE.PlaneBufferGeometry(), new THREE.MeshBasicMaterial( { color: 0x080808 } ) );  2 rectLightMesh.add( rectLightMeshBack );

上述代碼中,rectLightMesh表示的是我們上一步創建的平面光光源正面緩衝幾何體,rectLightMeshBack 表示是的我們創建的平面光光源反面平面緩衝幾何體,這一步中我們只需要將創建的反面平面緩衝幾何體添加到上一步創建的正面緩衝幾何體中即可。

平面光光源實例

實例效果圖如下:

 

實例介紹:

實例中,創建了一個平面,這個平面用來限定平面光光源的光照範圍,平面上創建了三個物體,分別是一個球體,一個正方體,一個管狀體。場景中添加了亮度為0.1的自然光,防止場景太黑影響視覺,也可襯托平面光光源。創建了亮度為1的平面光光源,在平面光光源位置添加了正反兩面平面緩衝幾何體。為了能夠更好地感受到平面光光源在應用中亮度與距離的關係,因此在實例中添加了動畫,用於隨機移動平面光光源。

實例預覽地址:深入理解three.js中平面光光源RectAreaLight

後話

希望上述講解能夠幫助到您,上述見解純屬個人理解,如果有理解不到位的或者表述有誤的還請留言說明,共同學習,共同進步。