大气光散射实施

时间:2016-05-08 12:00:03

标签: c++ opengl graphics shader light-scattering

我正在尝试在openGL中实现大气散射。我正在使用这篇“论文”作为教程: http://developer.amd.com/wordpress/media/2012/10/GDC_02_HoffmanPreetham.pdf

但是我在理解某些问题并找出一些常数时遇到了一些困难。

基本上我要实现这些公式: enter image description here

首先,我不知道s是从眼睛到圆顶的距离,还是从眼睛到光源(这里是太阳)位置的距离。 同样的角度θ我无法弄清楚它是从地面到太阳的角度还是眼睛看到的圆顶位置。

其次在本幻灯片中: 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

我只有蓝色,没有红色的夕阳,但是太阳很低,根据我看到的不同教程,我会看到当太阳降低时会出现一些红色。

1 个答案:

答案 0 :(得分:1)

警告我不是这个领域的专家,带着一粒盐。

s and Theta meanings 这几乎说明了一切。

s 是顶点/像素与相机之间的距离 θ是太阳和视线之间的角度。

为了计算θ,你需要知道“黄线”和“视线” 后者是普通的着色器数学;前者只是一种表达太阳在天空中有多高的方式。您可以将其建模为从太阳到地面点的光线。

以上所有公式都为您提供了矢量 L 0 是一个向量 E sun 也是一个向量。

幻灯片基本上表示 Radiance Irradiance (E sun )等物理概念在频谱上是连续的,应该使用用于描述灯光和颜色的光谱功率分布 然而,更快的方法是仅对光谱的三个点进行数学计算,一个用于R,G和B波长 在实践中,这表示 E sun 是描述三个RGB波长的太阳辐照度的矢量。

天空的蓝色来自参数β R ,它取决于θ,它取决于“视线”,这取决于片段的高度。天空是彩色的。