我目前使用以下代码在一个顶点着色器中创建雾:
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);
雾可以正常工作,但是问题是它只适用于此特定的着色器,而我希望雾可以应用于所有东西。
我该如何使用一种全局着色器来处理场景每个元素上的雾气?
答案 0 :(得分:0)
我该如何使用一种全局着色器来处理场景每个元素上的雾气?
您需要将雾计算合并到要用于呈现对象的每个程序对象中。
这不一定意味着您必须手动复制源代码。但是,您将需要一些管理着色器的基本策略。
您可以将多个着色器对象链接到一个舞台。这意味着您可以制作一个单独的顶点着色器,其中仅包含一个fogCalculations()
之类的函数,并从所有其他顶点着色器中调用它(当然也链接对象)。片段着色器部分也是如此。
您还可以以编程方式组合各个阶段的字符串,并在需要时基本注入雾代码。
还请注意您的雾度计算是错误的。您的visibility
不是线性属性,而是线性插值的(很好,在透视图划分之前是线性的,实际的计算在屏幕空间中将是非线性的,但这并不重要) 。如果您有一个沿观察方向大致延伸的大三角形,而一个基本上位于大三角形中心的小物体,则其可见性值将不同于三角形中心。此外,当三角形被裁剪时,在交点处新形成的顶点的visibility
也将关闭。
答案 1 :(得分:0)
来自derhass的答案是可行的,但要将计算合并到每个着色器中可能会有些痛苦。
另一种方法是拥有一个后期处理通道,在该通道中,您可以使用深度缓冲区来计算到相机的距离,然后对后期处理通道的像素着色器中的所有片段应用相同的算法。
您需要将以前的场景颜色和深度渲染到纹理上才能进行后期处理。