我正在尝试在 openGL 中实现大气散射。我正在使用这个“论文”作为教程:http: //developer.amd.com/wordpress/media/2012/10/GDC_02_HoffmanPreetham.pdf
但是,我很难理解某些观点并找出一些常数。
首先,我不知道 s 是眼睛到圆顶的距离还是眼睛到光源(这里是太阳)位置的距离。角度 theta 也是如此,我无法确定它是从地面到太阳的角度,还是到眼睛所看到的圆顶位置的角度。
其次在这张幻灯片中:
它告诉我天空会出现蓝色。我知道这是瑞利散射的原因,但有些事情我无法理解。上面公式中的所有计算都给了我一个标量:所以当我将它乘以标量时,基本上是 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;
}
我没有得到我所期望的,这是我得到的:
我只有蓝色,没有红色的日落,但是太阳很低,根据我看过的不同教程,当太阳下山时,我应该会看到一些红色的颜色。