點亮 WebXR 場景

因為 WebXR Device API 依賴於其他技術(即 WebGL 和基於它的框架)來執行場景的所有渲染、紋理和照明,所以相同的通用照明概念適用於 WebXR 設定或場景,就像適用於任何其他 WebGL 生成的顯示一樣。

然而,在建立照明程式碼時,需要牢記一些問題和細節,尤其是對於增強現實 (AR) 應用程式。本指南討論這些主題。雖然本文簡要提醒了照明的一般工作原理,但它絕不是照明教程,也不是關於如何建立正確照明的 3D 場景的指南。

回顧:3D 中的模擬照明

儘管本文不是 3D 場景照明的綜合指南,但簡要提醒照明的一般工作原理是很有用的。從根本上說,在虛擬場景中模擬照明涉及計算來自每個光源的光線在與場景中每個物件互動並反射後,眼睛接收到的光量。

光的反射

圖:顯示反射角如何與入射角對應的圖表。 A diagram showing how the angle of reflection corresponds to the angle of incidence.

我們所看到的每一個物體,我們之所以能看到,是因為物體要麼發光,要麼反射光(或兩者兼而有之)。入射光線(入射光線)以一個稱為入射角的角度到達。入射角 Θᵢ 是入射光線與表面法向量之間的夾角。

對於粗糙表面,光線向各個方向均勻反射。然而,光滑、鏡面般的表面將大部分光線反射到其反射角 Θᵣ 等於入射角的方向,只是它在法向量的另一側。那麼,反射光線就會沿著法向量離開。這就是反射定律。這是場景著色所涉及的大部分內容的基礎,並影響不同型別光源的行為方式。

當然,反射光線的顏色可能會因光線與表面的相互作用而改變強度和/或色調,但角度始終相同。

光源的組成部分

光源有三個主要組成部分;每個組成部分本質上是一種型別的光

有三種光可以影響物件及其畫素在檢視者螢幕或頭戴裝置上顯示的顏色和亮度。

環境光

環境光是不來自特定光源的光,而是遍佈整個場景的光。這種光以相同的強度從各個方向到達場景中的每個表面,然後向各個方向均勻反射。因此,環境光施加的效果在整個場景中普遍相同。

圖:一個只有環境光照的球體。請注意,完全沒有陰影來指示球體的深度。 A sphere which only has ambient lighting. Note the total lack of any shading to indicate the depth of the sphere.

環境光的效果是透過將光源強度乘以畫素位置處表面的反射率來計算的。場景中每個畫素的顏色和強度都以完全相同的方式受到影響,無論它在場景中的位置或朝向。環境光通常存在以防止陰影區域變得太暗,儘管它會影響整個場景;但是,場景中的環境光量應該非常低。

由於光的反彈和散射在即時計算中可能非常昂貴,尤其是涉及多個光源時,通常使用環境光來模擬場景中所有其他光源引起的散射光,而不是實際計算光散射的真實效果。然而,在這樣做時,需要注意儘量使環境光與場景照明的真實效果相匹配。

環境光還可以用於為場景應用顏色著色;例如,在一個玩家戴著一副黃色眼鏡的遊戲中,你可以新增黃色環境光。

漫射光

漫射光是均勻地、有方向地從表面發出或反射的光。這是我們通常看到的大部分光線。漫射光來自特定的位置或方向並投射陰影。由於其方向性,面向漫射光源的物件表面將比其他表面更亮。

圖:土星的第五大衛星土衛五,沐浴在陽光中,陽光來自左下方。 Saturn's fifth-largest moon, Tethys, is lit primarily by the sun, with some light reflected from Saturn. This is diffuse lighting.

由於漫射光的強度取決於入射角(表示光線從哪個方向到達表面的向量與表面法向量或垂直於表面的向量之間的夾角),因此物體反射光的強度或亮度會根據表面相對於光源的方向而變化。

鏡面光

鏡面光是構成反光物體上高光的光,例如寶石、眼睛、閃亮的杯子和盤子等。鏡面光往往以亮點或方塊的形式出現在光源最直接照射到表面的位置。

圖:NASA 的卡西尼號飛船拍攝的照片,顯示土星衛星土衛六表面液態甲烷湖的鏡面反射光。 A photo taken by NASA's Cassini spacecraft showing specular reflection of light from a lake of liquid methane on the surface of Saturn's moon Titan.

每個光源都由環境光、漫射光和/或鏡面光的某種組合表示。WebGL 著色器程式獲取每個光源的顏色、方向性、亮度和其它因素,並計算每個畫素的最終顏色。

光源型別

有四種基本光源型別。每一種都涉及一個虛擬光源,其與所繪製物件的距離以及光波的方向性導致光源呈現出特定的特徵。在大多數情況下,任何真實世界的光源都可以使用這些光源型別中的一種或多種來模擬。

環境光源

環境光源是描述場景中環境光強度和顏色的光源。雖然場景中可能存在多個這樣的光源,但您可以透過將它們組合成一個來稍微提高效能,因為每個光源無論如何都會均勻地影響每個畫素。

環境光源通常不對應場景中的任何物體,也沒有真實世界的對應物。

定向光源

定向光源是一種來自特定方向但並非來自特定光源的光源,因此其發射的光線彼此平行。此外,光的強度不隨距離變化。這意味著定向光投射的陰影非常銳利,光照和陰影之間幾乎是瞬時過渡。

圖:地球和月球都被太陽的定向光照亮一半。 A photo taken by the Galileo spacecraft from about 6.3 million kilometers away, with Earth and moon both half-lit by the sun.

定向光最常見的例子是太陽。雖然太陽實際上是一個單一的(大)物體,但它距離非常遙遠,所以從它發出的光線基本上是平行的。雖然陽光的強度確實會隨距離衰減,但變化率非常低,只有在很遠的距離才能察覺到,因此陽光強度變化率通常對渲染 3D 場景無關緊要。

點光源

點光源是位於特定位置、向各個方向均勻輻射的光源。燈泡、蠟燭等都是點光源的例子。物體離點光源越近,它投射到該物體上的光就越亮。點光源亮度衰減的速率稱為衰減,是 WebGL 和其他照明系統中光源的可配置特性。

在反射定律和光線亮度隨距離減小的作用下,點光源發出並反射回來的光線往往在離光源最近的點最亮,距離越遠越暗。即使表面是平坦的,離光源最近的點是中心,隨著偏離法線的角度變化,光線會越來越長。

聚光燈光源

聚光燈光源(或聚光燈)是一種位於特定位置的光源,以其方向向量的方向發出一個光錐。錐形衰減引數定義了光錐邊緣光的亮度衰減速度,並且,與點光源一樣,衰減引數控制光線隨距離的衰減。

圖:夜間聚光燈照射在灰泥牆上的照片。 Photo of a spotlight shining upon a stucco wall at night.

在光錐的邊緣,光線完全不再影響表面。

光照的計算成本

要可見,場景必須包含某種光照,因此所有或幾乎所有場景都至少會有一個光源,並且可能有很多光源。每個光源都會大幅增加計算每個顯示畫素的最終顏色和亮度所需的計算量。對這些光源型別中的每一種執行著色比前一種更具計算密集性;因此,環境光是最便宜的,其次是定向光源、點光源,最後是聚光燈。

此外,光照設計得越精確,計算成本就越高。增加陰影細節、體積光(即,在空氣中可以看到的光,例如陽光或天空中聚光燈的光束)以及其他光照效果可以為您的場景增加真實感和美感,但需要注意確保場景不會使 GPU 不堪重負。

計算受光畫素的顏色

雖然有些圖形庫支援光源物件並自動為您計算和應用光照效果,但 WebGL 不支援。幸運的是,在您自己的頂點和片段著色器中應用光照並不太困難。

對於場景中的每個多邊形,頂點著色器程式確定頂點顏色,然後片段著色器透過將分配紋理中相應的紋素、任何顏色著色或效果以及其他視覺資料組合起來,生成多邊形中的每個畫素。此時,場景的光照被考慮並適當地應用於畫素,然後畫素被儲存到幀緩衝區中。

最終渲染場景中每個畫素的顏色是使用一些複雜的數學計算的,這些數學考慮了以下因素:

  • 與螢幕畫素對應的紋理元素(對映到物件上的紋理中的畫素;也稱為紋素)的顏色,考慮到物件幾何形狀、檢視者相對於每個多邊形的位置和方向等。
  • 觀看者位置和距離。
  • 表面材料和反射率。
  • 目標位置表面凹凸性。
  • 場景中每個光源的位置、顏色、方向和亮度。
  • 場景中任何環境光的顏色和亮度;這種光均勻地應用於整個場景,沒有光源,因此沒有陰影或亮度變化。
  • 場景中其他表面反射光線的效果;反射光的顏色、方向和亮度將影響光線接觸到的畫素的顏色。

您可以在WebGL 中的光照文章中瞭解更多關於如何在 WebGL 中執行光照的資訊。

混合現實內容的照明問題

除了在照亮場景時需要處理的常見問題之外,VR 或 AR 用例在編寫著色器時還會增加額外的關注領域。在本節中,我們提供了一些基本的混合現實照明指南,供您在構建、渲染和照亮場景時考慮。雖然其中一些在任何其他 3D 環境中也很有用,但大多數是虛擬現實特有的,在某些情況下甚至更是增強現實特有的。

由於您的場景旨在代表一個人或其化身可以存在的環境,因此您應該嘗試在光源的定位和呈現方面實現一定程度的一致性和真實感。顯然,此指南也有例外情況,例如當您的場景代表超凡脫俗或外星環境時,或者當您的目標是建立令人不安的視覺效果時。

光源放置的真實感

在可能的情況下,您應該嘗試使您的虛擬光源與實際存在的物體相對應。如果您的虛擬房間需要頭頂照明,請在光源位置放置一個吸頂燈模型。也有例外,例如為您的設定新增基本照明量的環境光,以及太陽,它是一種定向光(即,光線都是平行且從天空中某個地方發出並最終到達場景中某個地方的光源)。

嘗試將光源放置在與您想要建立的場景和情緒相符的逼真位置。一個旨在營造自然光照、真實世界感覺的場景不應有演播室燈光。它有陽光,可能還有場景中物體或水反射的光線,等等,但不是直接照射到場景中物體或人物面部的燈光。

玩家與光線互動的真實感

如果您的光源位於場景中,您可能應該嘗試確保觀看者的化身不能與光源物理相交。結果可能會很奇怪。

如果觀看者的化身被設計為具有實體形態,即使觀看者永遠無法看到它,也應該有一個模型,以便光線與化身正確互動。最低限度,這意味著化身應該投射適當的陰影;但是,根據諸如化身是否可見以及其模型的材料、紋理和其他屬性(尤其是其反射率)等因素,化身可能還需要反射光線,並可能影響反射光的顏色。

增強現實中的真實感

增強現實為您的物件照明引入了額外的複雜性,因為您的虛擬物件需要存在於一個擁有自己光源的物理世界中。因此,您應該儘可能將您的照明與真實世界的物理光源匹配。這可以透過一種稱為照明估算的技術來完成。

反過來說,您應該儘量避免虛擬物體本身成為光源,除非您準備好建立可以將光線投射到真實世界環境中的程式碼。將光線投射到真實世界的物體上本質上與投射陰影相反。這可以做到,但尚未廣泛實現。

照明估算

照明估算是增強現實平臺使用的一種技術,旨在將場景中虛擬物體的照明與觀察者周圍真實世界的照明相匹配。這涉及收集可能來自各種感測器(包括加速度計和指南針,如果可用)、攝像頭以及其他可能來源的資料。其他資料透過 Geolocation API 收集,然後所有這些資料透過演算法和機器學習引擎生成估算的照明資訊。

目前,WebXR 不支援照明估算。然而,W3C 正在起草一份規範。您可以在規範的 GitHub 倉庫中包含的解釋性文件中瞭解有關提議的 API 以及照明估算概念的很多資訊。

本質上,照明估算收集有關光源以及場景中物件的形狀和方向的資訊,以及有關它們所製成的材料的資訊,然後返回可用於建立與真實世界照明近似匹配的虛擬光源物件的資料。

照明估算具體如何工作,尤其是在擬議的 API 上下文中,目前超出了討論範圍。一旦 API 穩定,我們將更新此文件以包含詳細資訊。

安全和隱私問題

為了使用真實世界資料生成和應用照明到虛擬物件,收集所有這些資料會帶來許多潛在的安全問題。

當然,許多 AR 應用都非常清楚使用者所在的位置。如果使用者正在執行一個名為《盧浮宮之旅》的應用,那麼使用者很可能位於法國巴黎的盧浮宮博物館。但瀏覽器被要求採取一系列措施,在未經使用者同意的情況下,使其難以物理定位使用者。

環境光感測器 API

使用 環境光感測器 API 收集光照資料會帶來各種潛在的隱私問題。

  • 光照資訊可能會洩露使用者周圍環境和裝置使用模式的網站資訊。此類資訊可用於增強使用者畫像和行為分析資料。
  • 如果兩個或更多裝置訪問使用相同第三方指令碼的內容,該指令碼可用於關聯光照資訊及其隨時間的變化,以嘗試確定裝置之間的空間關係;例如,這理論上可以表明這些裝置位於同一大致區域。

瀏覽器如何緩解這些問題

為了幫助緩解這些風險,WebXR 照明估算 API 規範要求瀏覽器報告的照明資訊與真實值有所出入。有許多方法可以做到這一點。

球諧函式精度

瀏覽器可以透過降低球諧函式的精度來降低指紋識別的風險。在執行即時渲染時(虛擬或增強現實應用程式都是如此),球諧函式照明用於簡化和加速生成高度逼真的陰影和著色過程。透過改變這些函式的準確性,瀏覽器使資料的一致性降低,並且重要的是,即使在相同的設定下,兩臺計算機生成的資料也會有所不同。

將方向與照明解耦

在利用地理定位來確定方向和潛在位置資訊的 AR 應用中,避免讓該資訊直接與照明狀態相關聯是瀏覽器保護使用者免受指紋識別攻擊的另一種方式。透過確保指南針方向和光線方向在使用者附近(或聲稱附近)的每個裝置上都不相同,可以消除根據周圍照明狀態找到使用者的能力。

當瀏覽器提供關於一個非常明亮的定向光源的詳細資訊時,該光源很可能代表太陽。這個明亮光源的方向性與一天中的時間結合起來,可以用來確定使用者的地理位置,而無需涉及地理定位 API。透過確保 AR 場景的座標不與指南針座標對齊,並透過降低太陽光角度的精度,就無法再使用這種技術準確估算位置。

時間和空間濾波

考慮一種攻擊,它使用建築物的自動化照明系統以已知模式快速開關燈。如果沒有適當的預防措施,照明估算資料可能被用來檢測這種模式,從而確定使用者位於特定位置。這可以透過遠端完成,或者由位於同一房間但想確定另一個人是否也在同一房間的攻擊者執行。

照明估算可在未經許可的情況下獲取使用者資訊的另一個場景:如果光感測器足夠靠近使用者顯示器,可以檢測到由顯示器內容引起的光照變化,則可以使用演算法來確定使用者是否正在觀看特定影片——甚至可能識別使用者正在觀看的多個影片中的哪一個。

照明估算 API 規範規定所有使用者代理都必須執行時間濾波和空間濾波,以模糊資料,從而降低其用於定位使用者或執行旁道攻擊的實用性。

另見