OpenGL:防止在每个着色器程序中产生雾

时间:2018-07-17 18:09:53

标签: opengl shader

我目前使用以下代码在一个顶点着色器中创建雾:

float Distance = length(PositionToCam.xyz);
Visibility = exp(-pow((Distance*Density), Gradient));
Visibility = clamp(Visibility, 0.0, 1.0);

然后,我像这样在片段着色器中使用Visibility

FragColor = mix(vec4(SkyColor, 1.0), FragColor, Visibility);

雾可以正常工作,但是问题是它只适用于此特定的着色器,而我希望雾可以应用于所有东西。

我该如何使用一种全局着色器来处理场景每个元素上的雾气?

2 个答案:

答案 0 :(得分:0)

  

我该如何使用一种全局着色器来处理场景每个元素上的雾气?

您需要将雾计算合并到要用于呈现对象的每个程序对象中。

这不一定意味着您必须手动复制源代码。但是,您将需要一些管理着色器的基本策略。

  1. 您可以将多个着色器对象链接到一个舞台。这意味着您可以制作一个单独的顶点着色器,其中仅包含一个fogCalculations()之类的函数,并从所有其他顶点着色器中调用它(当然也链接对象)。片段着色器部分也是如此。

  2. 您还可以以编程方式组合各个阶段的字符串,并在需要时基本注入雾代码。

还请注意您的雾度计算是错误的。您的visibility不是线性属性,而是线性插值的(很好,在透视图划分之前是线性的,实际的计算在屏幕空间中将是非线性的,但这并不重要) 。如果您有一个沿观察方向大致延伸的大三角形,而一个基本上位于大三角形中心的小物体,则其可见性值将不同于三角形中心。此外,当三角形被裁剪时,在交点处新形成的顶点的visibility也将关闭。

答案 1 :(得分:0)

来自derhass的答案是可行的,但要将计算合并到每个着色器中可能会有些痛苦。

另一种方法是拥有一个后期处理通道,在该通道中,您可以使用深度缓冲区来计算到相机的距离,然后对后期处理通道的像素着色器中的所有片段应用相同的算法。

您需要将以前的场景颜色和深度渲染到纹理上才能进行后期处理。