2016-05-08 79 views
1

我試圖在openGL中實現大氣散射。我正在使用這個「紙」作爲教程: http://developer.amd.com/wordpress/media/2012/10/GDC_02_HoffmanPreetham.pdf大氣光散射實現

但是我有一些困難,理解某些觀點並找出一些常數。

基本上我已經實現這些公式: enter image description here

首先,我不知道,如果s是從眼睛到穹頂或距離眼睛到光源(太陽在這裏)的位置的距離。 同樣的角度theta我無法弄清楚,如果它是從地面到太陽的角度或眼睛在看的圓頂位置。

其次在這張幻燈片中: enter image description here 它告訴我天空的藍色將出現。我知道這是瑞利散射的原因,但有一些我不明白。上述公式中的所有計算都給了我一個標量:太陽的白光如何基本上是一個vec3(1,1,1),當我將它乘以標量時它將變成藍色,它只會變成灰度因爲我會得到結果,例如vec3(0.8,0.8,0.8)。我的意思是,如果出現一些不同的天空顏色,我必須用vec3乘以太陽光來改變RGB值。

現在我遇到了一些困難來實現我的着色器。 這裏是天空着色器代碼:

#version 330 

in vec3 vpoint; 

in vec2 vtexcoord; 


out vec2 uv; 


out vec3 atmos; 


uniform mat4 M; 

uniform mat4 V; 

uniform mat4 P; 


mat4 MVP = P*V*M; 



//uniform vec3 lpos; 

vec3 lpos = vec3(100,0,0); 

uniform vec3 cpos; 



vec3 br = vec3(5.5e-6, 13.0e-6, 22.4e-6); 

vec3 bm = vec3(21e-6); 





float g = -0.75f; 


vec3 Esun = vec3(2000,2000,2000); 




vec3 Br(float theta){ 
return 3/(16*3.14) * br * (1+cos(theta)*cos(theta)); 

} 


vec3 Bm(float theta){ 
return 1/(4*3.14) * bm * ((1 - g)*(1 - g))/(pow(1+g*g- 
2*g*cos(theta),3/2)); 

} 


vec3 atmospheric(float theta, float s){ 
return (Br(theta)*Bm(theta))/(br+bm) * Esun * (1- exp(-(br+bm)*s)); 

} 


void main() { 

gl_Position = MVP * vec4(vpoint, 1.0); 
uv = vtexcoord; 

vec3 domePos = vec3(M*vec4(vpoint,1.0)); 

vec3 ldir = lpos - domePos; 

float s = length(domePos-cpos); 
float theta = acos(dot(normalize(ldir-domePos),normalize(domePos- 
cpos)*vec3(1,1,0))); 

atmos = atmospheric(theta,s)*1000000*5; 

} 

我沒有得到什麼,我希望,這裏是我得到:

enter image description here

我只有藍,沒有紅日落,但太陽很低,根據我所看到的不同教程,當太陽變低時,我會看到一些偏紅的顏色。

+0

「*太陽白光*」太陽不會發出白光。 –

+0

@JimZer只是一個打賭(太懶惰來分析你的代碼)在太陽附近你的照度過飽和(遠遠高於圖像顏色深度),所以它被截斷爲白色。您應該將所有通道截斷爲單個矢量而不是每個通道。也看看我的散射http://stackoverflow.com/a/19659648/2521214它更簡單 – Spektre

回答

1

警告我不是這方面的專家,請帶上一粒鹽。

s and Theta meanings 這幾乎說明了一切。

s是頂點/像素和相機之間的距離。
θ是太陽和視線之間的角度。

爲了計算θ您需要知道「黃線」和「視線」。
後者是普通的着色器數學;前者只是表達太陽在天空中有多高的一種方式。您可以將它建模爲從太陽射到地面上的一個點。


上述所有公式給出了向量。
L是一個載體。
E 太陽也是一個載體。

幻燈片基本上說,物理概念,如光輝輻照(E 太陽)都在頻譜連續和一個應該使用光譜功率分佈來形容燈光和顏色。
然而,一種更快的方法是僅在光譜的三個點上進行數學運算,即R,G和B波長。
實際上這說E 太陽是一個矢量描述三個RGB波長太陽的輻照度。

天空的藍色來自參數β ř取決於θ其取決於「視線」,這取決於天空的片段的高度被着色。

+0

不錯,我可以更好地理解。 但是我只有藍色的,沒有紅色的日落,但太陽很低,根據我所看到的不同教程,當太陽變低時,我會看到一些偏紅的顏色。 我用iI可以得到的更新我的帖子: 你有什麼想法嗎? – JimZer