C++ 大气光散射实现

C++ 大气光散射实现,c++,opengl,graphics,shader,light-scattering,C++,Opengl,Graphics,Shader,Light Scattering,我试图在openGL中实现大气散射。我将此“论文”用作教程: 然而,我在理解某些要点和找出一些常数方面有一些困难 基本上,我必须实现这些公式: 首先,我不知道s是眼睛到圆顶的距离,还是眼睛到光源(这里是太阳)的距离。 角度θ也是一样,我不知道这是从地面到太阳的角度,还是眼睛所看到的圆顶的角度 第二,在本幻灯片中: 它告诉我天空将呈现蓝色。我知道这是瑞利散射的原因,但有些事情我不明白。上面公式中的所有计算都给了我一个标量:所以太阳的白光基本上是一个vec3(1,1,1),当我将它乘以标量时,它

我试图在openGL中实现大气散射。我将此“论文”用作教程:

然而,我在理解某些要点和找出一些常数方面有一些困难

基本上,我必须实现这些公式:

首先,我不知道s是眼睛到圆顶的距离,还是眼睛到光源(这里是太阳)的距离。 角度θ也是一样,我不知道这是从地面到太阳的角度,还是眼睛所看到的圆顶的角度

第二,在本幻灯片中: 它告诉我天空将呈现蓝色。我知道这是瑞利散射的原因,但有些事情我不明白。上面公式中的所有计算都给了我一个标量:所以太阳的白光基本上是一个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;

}
我没有得到我期望的,以下是我得到的:


我只有蓝色,没有redish日落,但是太阳很低,根据我看过的不同教程,当太阳很低时,我会看到一些redish颜色出现。

警告我不是这方面的专家,对此持保留态度

这几乎说明了一切

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

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


上面所有的公式都给出了向量。
L0是一个向量。
Esun也是一个向量

幻灯片基本上说,辐射度和辐照度(Esun)等物理概念在光谱上是连续的,应该使用光谱功率分布来描述光和颜色。
然而,一种更快的方法是只对光谱的三个点进行计算,一个是R、G和B波长的点。
实际上,这表示Esun是一个矢量,用于描述三个RGB波长的太阳辐照度


天空的蓝色来自参数βR,它取决于θ,θ取决于“视线”,而“视线”取决于被着色天空碎片的高度

“太阳的白光”太阳不会发出白光。@JimZer只是在太阳附近下注(懒得分析代码)你的照明过度饱和(比图像颜色深度高得多),所以它被截断为白色。您应该将所有通道截断为单个向量,而不是每个通道。再看看我的散射图,它有点简单,我能更好地理解。然而,我只有蓝色,没有redish日落,但是太阳很低,根据我看过的不同教程,当太阳变低时,我应该会看到一些redish颜色出现。我用我能得到的更新我的帖子:你有什么想法吗?