大气光散射实施

问题描述 投票:0回答:1

我很难理解某些要点并找出一些常数。 从大多数情况下,我已经实施了这些公式:

首先,我不知道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

我只有蓝色,没有淡淡的日落,但太阳很低,根据我所见过的不同教程,当太阳变低时,我应该看到一些红色的颜色。
    

warning

我不是这个领域的专家,请用一粒盐来服用。 enter image description here

这几乎说明了一切。
c++ opengl graphics shader light-scattering
1个回答
1
投票
S

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

为了计算θ,您需要知道“黄线”和“视线”。 后者是普通的着色器数学;前者只是表达太阳在天空中有多高的一种方式。您可以将其建模为从太阳到地面上的一个点的射线。 上面的所有公式都为您提供向量。 s and Theta meaningsl0是向量。

e

sun也是向量。
幻灯片基本上说,诸如radiance

irradiance
(e

sun
)之类的物理概念在频谱上是连续的,并且应该使用

光谱的功率分布来描述灯光和颜色。 但是,更快的方法是仅在三个点上进行数学,这是R,G和B波长的一个。 实际上,这说明
esun是描述三个RGB波长太阳的辐射的矢量。
天空的蓝色来自参数βR,该参数取决于θ,该参数取决于“视线”,这取决于天空碎片的高度。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.