如何实现地面雾GLSL着色器

Vyl*_*ain 6 opengl shader glsl

我正在尝试为我的地形渲染引擎实现地面雾着色器.本文介绍了该技术:http://www.iquilezles.org/www/articles/fog/fog.htm

我们的想法是考虑从相机到碎片的光线,并沿着这条光线集成雾密度函数.

这是我的着色器代码:

#version 330 core
in vec2 UV;
in vec3 posw;

out vec3 color;

uniform sampler2D tex;

uniform vec3 ambientLightColor;
uniform vec3 camPos;

const vec3 FogBaseColor = vec3(1., 1., 1.);

void main()
{
    vec3 light = ambientLightColor;
    vec TexBaseColor = texture(tex,UV).rgb;

    //***************************FOG********************************************
    vec3 camFrag = posw - camPos;
    float distance = length(camFrag);
    float a = 0.02;
    float b = 0.01;

    float fogAmount = a * exp(-camPos.z*b) * ( 1.0-exp( -distance*camFrag.z*b ) ) / (b*camFrag.z);
    color = mix( light*TexBaseColor, light*FogBaseColor, fogAmount );
}
Run Code Online (Sandbox Code Playgroud)

第一件事是我不明白如何选择a和b以及它们在雾密度函数中的物理作用.

然后,结果不是我所期望的......我有一个地面雾,但是fogAmount从0到1的转换总是以摄像机高度为中心.我已经尝试了很多不同的a和b但是当我没有在相机高度进行过渡时,我要么在所有地形都有一个完全模糊或没有模糊.

我检查了我使用的数据,一切都是正确的:

  • camPos.z是我相机的高度
  • camFrag.z是从摄像机到片段的矢量的垂直分量

我无法理解等式中的哪一部分会导致这种情况.

对此有何想法?

编辑:这是我正在寻找的效果: image1 image2

And*_*man 5

这是大气散射的相当标准的应用。

通常在体积照明的保护下进行讨论,这涉及光通过不同介质(例如烟,空气,水)的透射率。在基于着色器的尖端图形中,可以使用光线行进或仅存在一种统一的参与介质(在这种情况下,雾仅适用于空气)实时实现,简化了集成在一段距离上。

通常,您将对参与的介质进行射线行进以确定光传输的属性,但是将此应用程序简化为假设一种介质,该介质具有明确定义的分布特性,这就是您困惑的系数的来源。雾的密度随距离呈指数变化,这是要b控制的,同样,它也随高度变化(在下面的方程式中直接显示)。

   
(来源:iquilezles.org

但是,本文介绍的讨论内容的名称a和系数很差b。这些控制了散射和消光。笔者多次提到的消光系数为extintion,这真的是没有意义的我-希望这仅仅是因为英语不是作者的母语。可以认为消光是吸收光线的速度,它描述了介质的不透明性。如果您想为所有这些提供更多的理论基础,请查看以下文章

考虑到这一点,再看一下文章中的代码:

vec3 applyFog( in vec3  rgb,      // original color of the pixel
               in float distance, // camera to point distance
               in vec3  rayOri,   // camera position
               in vec3  rayDir )  // camera to point vector
{
    float fogAmount = c*exp(-rayOri.y*b)*(1.0-exp(-distance*rayDir.y*b))/rayDir.y;
    vec3  fogColor  = vec3(0.5,0.6,0.7);
    return mix( rgb, fogColor, fogAmount );
}
Run Code Online (Sandbox Code Playgroud)

c实际上可以a从原始方程式的代码中看到这一点。

更重要的是,这里还有一个附加表达式:

   LaTeX方程

该附加表达式控制相对于高度的密度。从着色器的实现来看,您没有正确实现第二个表达式。camFrag.z很可能不是高度,而是深度。此外,我不明白您为什么要乘以b系数。


Vyl*_*ain 5

我找到了一种方法,可以给出我正在寻找的结果。

该方法在 Eric Lengyel 的这篇文章中有描述:[链接] http://www.terathon.com/lengyel/Lengyel-UnifiedFog.pdf

它解释了如何使用密度和高度参数创建雾层。您可以飞过它,它会逐渐融合雾上方的所有几何体。