代码之家  ›  专栏  ›  技术社区  ›  Trytio

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

  •  0
  • Trytio  · 技术社区  · 7 年前

    当前,我的一个顶点着色器中有一个雾,代码如下:

    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 回复  |  直到 7 年前
        1
  •  0
  •   derhass    7 年前

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

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

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

    1. 可以为单个阶段将多个着色器对象链接在一起。这意味着您可以创建一个单独的顶点着色器,它只包含一个类似于 fogCalculations() 只需从所有其他顶点着色器调用它(当然还要链接对象)。片段着色器部分也是如此。

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

    还要注意,您的雾计算是错误的。你的 visibility 不是线性属性,但它将是线性插值(好吧,线性w.r.t.透视图分割前的空间,实际计算在屏幕空间将是非线性的,但这并不重要)。如果有一个大致沿观察方向延伸的大三角形,以及一个基本上位于大三角形中心的小对象,则它将收到与三角形中心不同的可见性值。而且,当你的三角形被剪掉时 可见度 对于交点处新形成的顶点也将禁用。

        2
  •  0
  •   florent teppe    7 年前

    来自derhass的答案是可行的,但是将计算合并到每个着色器中可能会有点麻烦。

    另一种方法是使用后处理过程,在该过程中使用深度缓冲区计算到摄影机的距离,然后对后处理过程的像素着色器中的所有片段应用相同的alogorithm。

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