標籤:highlight 理解 方法 int div 部分 原因 邏輯 pap
這次先上*4
散射概念
光線擊中空氣中的微小顆粒後的偏折導致了光線的散射。我們看到的陽光應該是由視線上的散射在視線方向上的集合。如果由地面的反射,還要加上經過散射計算的地面反射。
Rayleigh散射
由較小的空氣分子引起的散射,對不同波長的光有不同的散射程度,藍色最強。也就是天空為啥是藍色的原因。
Mie散射
由較大的漂浮顆粒(氣溶膠……PM2.5????)導致的散射
相位方程
相位方程描述有多少光會倍散射到相機方向上。
θ:採樣點處光線(太陽到採樣點)和視線(相機到採樣點)的角度。
g:影響對稱性,對Rayleigh散射,g可以取0。對Mie散射,g一般是在-0.75到-0.999之間。
外散射
就是計算散射對光的影響
4π:外散射是向散射點為球心的球面上均勻散射的,所以這個是球表面積,單方向的散射就沒有4π了
光深(optical depth ): 就是公式的積分部分,可以理解為兩點間的平均大氣密度,這個值顯然跟高度有關係。h就是歸一化之後的採樣點高度。H0大氣平均密度高度,可以理解為在這裡密度是1。選取的值是0.25。
散射係數K(λ):散射係數,這個係數跟海平面大氣密度有關,也跟波長有關。不過rayliegh和mie都有所不同,比如大部分mie的實現是忽略波長的。
內散射
散射在視線方向上的集合,整個公式就是不進行球面積分的散射。
採樣點處的兩個外散射:採樣點到相機和太陽到採樣點的散射
Is(λ):光強度,可以在這裡修改太陽光色,正常按白色就可以差不多。
表面散射
表面散射就是將地表的反射光/自發光進行到相機的散射處理
Ie(λ):地表發出的光(反射/自發光)。這有兩個方案:1.認為地表自發光,地表的顏色就是這個值。2.認為地表的光是反射,在計算反射之前,要算上入射光經過大氣層的散射,所以這個值要比沒有大氣直接反射小。
注意:這個方案中忽略了反射方向上的散射積分,所以地表顏色會有點片暗。
簡化計算
進行歸一化,將從海平面到大氣上界的高度值scale到0~1
預計算查詢表
將積分採樣計算預先進行,產生相應的查詢表
太陽光在大氣內散射的預計算
將陽光認為是平行光,此時可以用高度和與平行光的角度來描述大氣層內的任意一點,不唯一的點數值也都是一樣的。
更好的預計算方法
上一個預計算方法只能解決兩個外散射計算中的太陽光散射部分,怎麼把視線散射部分也解決?
對於一個均勻大氣層來說,任意一點按一定角度到任意方向大氣上界的射線,都可以用射線發起點高度,和一個位移角來描述。這個射線可以既可以用在光線方向的散射計算,也可以用在視線方向的散射計算,只要能描述兩條射線就都沒問題。
這樣只要預先計算採樣射線上的光深和大氣密度(exp(-h/H0)),這樣兩個外散射積分就都不用計算了
使用預計算表注意
預計算表存的都是從採樣點到大氣上界的值,要是相機在大氣內,是需要剪掉同方向上從相機位置到大氣上界的相應計算結果的。
這種情況下如果採樣點(定點)在相機上方,有可能出現計算用的射線穿過地表的情況,這個時候在低精度的shader中肯定由精度問題。於是將射線方向反轉,向採樣點方向取兩個射線,計算結果是一樣的(距離一樣)。
Shader實現
shader的思路是不使用預計算,而用結果近似的簡單計算。用一點效率來降低shader的硬體需求。
消除預計算表取值
使用x=0(海平面)的曲線將其他採樣曲線歸一化得到這個結果
v = exp(-4x)*scale(y)
scale(y),就是海平面處的曲線。這樣x軸就被幹掉了
這個scale曲線並沒有什麼通用的方案,是使用曲線擬合獲得的一個多項式計算公式。於是這個實現有一個問題就是:**如果scale height(平均密度高度)不是0.25(從海面到大氣上界的25%),這個scale的近似公式就要重新進行曲線擬合**
4個shader
首先地面和天空的頂點計算完全不同。另外要解決之前提到的大氣內取值的問題,在大氣內會有一些計算是大氣外不需要的。為了減少shader內的邏輯判斷所以分成4個shader,從大氣看地面,從宇宙看地面,從宇宙看天空,從大氣看天空。
一些奇怪的參數
有一些參數非常的怪異,文章中並沒有什麼說明。稍微說一說,省得以後自己忘了。
單位:波長的單位一般是nm,10^-9m。海平面分子數密度,2.55*10^25。 這種計算float基本不行了,所以在單位上要進行一些修正。由於Rayleigh中的散射係數是跟λ^4相關的,將λ變成10^-3單位,每個乘了10^6,4次就是10^24。這就幾乎沒有0 了。
Kr,4πKr:Kr是Rayleigh的散射係數。這裡取值是0.0025。
我計算了一下β
這個結果和
[Efficient Rendering of Atmospheric Phenomena]中的基本相似
但是這時計算的K是 9.3 * 10^-8 這個我立刻就方了。根本不一樣好不好,差好幾個數量級呢!(差了3.72*10^-5)
我現在還沒有想通,猜測有兩個方向:1.光深計算上的區別,2.高度歸一化的影響。四處看了幾天也沒有結果,下次我繼續搞Eric.Bruneton那個計算了多重散射的再繼續研究
Km,4πKm: Km是Mie散射的係數,也一樣有很讓人迷惑的計算結果
g:一個影響散射對稱性的參數。
在[Display_of_The_Earth_Taking_into_Account_Atmospheric_Scattering]裡面有一點說明,不過更詳細的在另外一篇文章。
u和空氣品質相關,0.7~0.85
不過基本上對Rayleigh散射g=0,對Mie散射在-0.75到-0.999之間
---
需要測試的問題以及額外的研究
大氣內shader
產生預計算表,改成取值形式的shader
g對散射效果的影響
H0對散射效果的影響
參與散射的雲
分開Mie和Rayleigh的相關計算
表面散射使用反射機制
表面散射增加視線上的散射積分
HDR 更豐富的戰線
題外話
在研究散射係數的時候真的是很有一點挫敗感,感覺雖然GPU Gems這書裡面提供了一個很好的實現,但是道理講得就有點模糊,想要繼續挖掘的時候就顯得很尷尬。
之後會作幾個簡單的改進,至少實現預計算取值形式的shader和簡單的工具。再之後的……如果有作宇宙題材遊戲的機會再進一步研究吧
大氣散射 GPU Gems2 Chapter 16. Accurate Atmospheric Scattering