詳解Threejs中的光源對象


光源的分類

  1. AmbientLight(環境光),PointLight(點光源),SpotLight(聚光源) 和 DirectionalLight(平行光)是基礎光源
  2. HemisphereLight(半球光源),AreaLight(區域光源),LensFlare(鏡頭光暈) 是有特殊用途的光源

半球光源 HemisphereLight

  • 半球光直接放置於場景之上,光照顏色從天空光線顏色顏色漸變到地面光線顏色
  • 半球光不能投射陰影
  • 半球光可以創建出更加貼近自然的戶外光照效果,就是為了模擬在戶外場景中的反光效果

半球光源的應用

如果不使用 THREE.HemisphereLight,要模擬戶外光照,通常是創建一個 THREE.DirectionalLight 來模擬太陽光,並且可能再添加一個 THREE.AmbientLight 來為場景提供基礎色

半球光源的常用屬性

  • color:從天空發出的光線的顏色
  • groundColor:從地面發出的光線的顏色
  • intensity:光源照射的強度。默認值為:1。
  • position:光源在場景中的位置。默認值為:(0, 100, 0)
  • visible:設為 ture(默認值),光源就會打開。設為 false,光源就會關閉。

半球光源的代碼示例

var hemiLight = new THREE.HemisphereLight(天空的反光顏色,地面的反光顏色,光的強度)
// 這個也是默認位置
hemiLight.position.set(0, 100, 0)
scene.add(hemiLight)

環境光 AmbientLight

  • 環境光是沒有特定方向的光源,會均勻的照亮場景中的所有物體,主要是均勻整體改變Threejs物體表面的明暗效果,這一點和具有方向的光源不同,比如點光源可以讓物體表面不同區域明暗程度不同
  • 環境光影響整個場景,它的光線沒有特定來源但是又無處不在,它不能影響陰影生成,因為它沒有方向,並且不能作為唯一光源,使用其他光源的同時使用 THREE.AmbientLight,目的是弱化陰影和添加一些顏色

環境光的代碼示例

// THREE.AmbientLight不需要指定位置,只需要指定顏色(十六進制)
var ambientLight = new THREE.AmbientLight(0x0c0c0c)
scene.add(ambientLight)

環境光和半球光源的區別

  • 環境光分為 THREE.AmbientLight & THREE.HemisphereLight
  • THREE.AmbientLight 物體明暗對比無法呈現
  • THREE.HemisphereLight 物體明暗對比比較明顯
  • 如果想模擬真實世界,建議用THREE.HemisphereLight,如果對三維的展現不是特別苛刻,可以用 THREE.AmbientLightTHREE.DirectionalLight

點光源 PointLight

  • 點光源就像生活中的白熾燈,光線沿着發光核心向外發散,同一平面的不同位置與點光源光線入射角是不同的,點光源照射下,同一個平面不同區域是呈現出不同的明暗效果
  • 和環境光不同,環境光不需要設置光源位置,而點光源需要設置位置屬性.position,光源位置不同,物體表面被照亮的面不同,遠近不同因為衰減明暗程度不同

點光源的代碼示例

var point = new THREE.PointLight(0xffffff)
//設置點光源位置,改變光源的位置
point.position.set(400, 200, 300)
scene.add(point)

平行光 DirectionalLight

  • 平行光顧名思義光線平行,對於一個平面而言,平面不同區域接收到平行光的入射角一樣
  • 點光源因為是向四周發散,所以設置好位置屬性.position就可以確定光線和物體表面的夾角
  • 對於平行光而言,主要是確定光線的方向,光線方向設定好了,光線的與物體表面入射角就確定了,僅僅設置光線位置是不起作用的
  • 在三維空間中為了確定一條直線的方向只需要確定直線上兩個點的坐標即可,所以平行光提供了位置.position和目標.target兩個屬性來一起確定平行光方向
  • 目標.target的屬性值可以是場景中任何一個三維模型對象,比如一個網格模型Mesh,平行光會通過自身位置屬性.position.target表示的物體的位置屬性.position計算出來
  • 平行光如果不設置.position.target屬性,光線默認從上往下照射,也就是可以認為(0,1,0)(0,0,0)兩個坐標確定的光線方向
  • 注意一點平行光光源的位置屬性.position並不表示平行光從這個位置向遠處照射,.position屬性只是用來確定平行光的照射方向,平行光你可以理解為太陽光,從無限遠處照射過來

平行光的代碼示例

var directionalLight = new THREE.DirectionalLight(0xffffff, 1)
// 設置光源的方向:通過光源position屬性和目標指向對象的position屬性計算
directionalLight.position.set(80, 100, 50)
// 方向光指向對象網格模型mesh,可以不設置,默認的位置是0,0,0
directionalLight.target = mesh
scene.add(directionalLight)

聚光源 SpotLight

  • 聚光源可以認為是一個沿着特定方會逐漸發散的光源,照射范圍在三維空間中構成一個圓錐體
  • 通過屬性.angle可以設置聚光源發散角度,聚光源照射方向設置和平行光光源一樣是通過位置.position和目標.target兩個屬性來實現

聚光源的代碼示例

var spotLight = new THREE.SpotLight(0xffffff)
spotLight.position.set(200, 200, 200)
spotLight.target = mesh
// 設置聚光光源發散角度
spotLight.angle = Math.PI / 6
scene.add(spotLight)//光對象添加到scene場景中

什么是光投影

在具有方向光源的作用下,物體會形成陰影投影效果

如何光投影計算

Three.js物體投影模擬計算主要設置三部分

  1. 一個是設置產生投影的模型對象
  2. 一個是設置接收投影效果的模型
  3. 最后一個是光源對象本身的設置,光源如何產生投影

平行光投影計算代碼示例

// 創建方向光光源
var directionalLight = new THREE.DirectionalLight(0xffffff, 1)
directionalLight.position.set(60, 100, 40)
scene.add(directionalLight)

// 設置用於計算陰影的光源對象
directionalLight.castShadow = true

// 設置計算陰影的區域,最好剛好緊密包圍在對象周圍,如果計算陰影的區域過大:模糊,如果過小:看不到或顯示不完整
directionalLight.shadow.camera.near = 0.5
directionalLight.shadow.camera.far = 300
directionalLight.shadow.camera.left = -50
directionalLight.shadow.camera.right = 50
directionalLight.shadow.camera.top = 200
directionalLight.shadow.camera.bottom = -100

// 設置mapSize屬性可以使陰影更清晰,不那么模糊
// directionalLight.shadow.mapSize.set(1024,1024)

聚光源投影計算代碼示例

// 創建聚光光源
var spotLight = new THREE.SpotLight(0xffffff)
spotLight.position.set(50, 90, 50)
spotLight.angle = Math.PI /6
scene.add(spotLight)


// 設置用於計算陰影的光源對象
spotLight.castShadow = true

// 設置計算陰影的區域,注意包裹對象的周圍
spotLight.shadow.camera.near = 1
spotLight.shadow.camera.far = 300
spotLight.shadow.camera.fov = 20

光投影計算的常用屬性

  • 模型.castShadow屬性,.castShadow屬性值是布爾值,默認false,用來設置一個模型對象是否在光照下產生投影效果
  • 模型.receiveShadow屬性,.receiveShadow屬性值是布爾值,默認false,用來設置一個模型對象是否在光照下接受其它模型的投影效果
  • 光源.castShadow屬性,如果屬性設置為true, 光源將投射動態陰影,警告: 這需要很多計算資源,需要調整以使陰影看起來正確
  • 光源.shadow屬性

    平行光DirectionalLight.shadow屬性值是平行光陰影對象DirectionalLightShadow
    聚光源SpotLight.shadow屬性值是聚光源陰影對象SpotLightShadow

  • 陰影對象基類LightShadow

    LightShadow屬性.camera,觀察光源的相機對象,從光的角度來看,以相機對象的觀察位置和方向來判斷,其他物體背后的物體將處於陰影中
    LightShadow屬性.mapSize,定義陰影紋理貼圖寬高尺寸的一個二維向量Vector2,
    較高的值會以計算時間為代價提供更好的陰影質量,寬高分量值必須是2的冪直到給定設備的WebGLRenderer.capabilities.maxTextureSize
    盡管寬度和高度不必相同 (例如,(512, 1024)是有效的),默認值為 ( 512, 512 )
    LightShadow屬性.map,該屬性的值是WebGL渲染目標對象WebGLRenderTarget,使用內置攝像頭生成的深度圖,超出像素深度的位置在陰影中,在渲染期間內部計算

參考文檔一 ———— Threejs光源對象
參考文檔二 ———— HemisphereLight和AmbientLight 區別
參考文檔三 ———— Threejs官方示例

我是 fx67ll.com,如果您發現本文有什么錯誤,歡迎在評論區討論指正,感謝您的閱讀!
如果您喜歡這篇文章,歡迎訪問我的 本文github倉庫地址,為我點一顆Star,Thanks~ 😃
轉發請注明參考文章地址,非常感謝!!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM