如何在OpenGL中创建深度淡化效果?

时间:2017-05-10 21:03:32

标签: c++ opengl fragment-shader

我想创建一个半透明的球体,它在与其他物体(例如地面)相交的地方突出显示。

就像这张图片中的白线一样:

https://github.com/jacoco/jacoco/issues/531

我发现image关于如何创建类似的内容。

它使用"深度淡化"在着色器中。很遗憾,我还没有找到任何关于Depth Fades的OpenGL教程。

如何创建这样的效果?

1 个答案:

答案 0 :(得分:6)

不确定。我不确切地知道Unreal对它的意义,但总体思路如下。

首先,您需要一个可读的深度缓冲区。这意味着要么进行深度预处理,要么在之后渲染这个特殊效果你已经渲染了场景中的不透明对象(你想要这个球体相交的对象)。我将假设你知道或者可以弄清楚如何创建和使用你自己的深度缓冲区,以便你可以在后面的步骤中阅读它。您将无法使用GL的默认深度缓冲区(因此您需要帧缓冲对象,颜色附件,深度附件)。

现在,让我们谈谈渲染球体。在顶点着色器中,您需要:

  • 像往常一样转换顶点
  • 转换后,将顶点的深度值写入变化的(您需要在片段着色器中使用它)

因此,顶点着色器的目的是计算球体的场景深度并将其传递给片段着色器。

片段着色器中,您可以使用此技术。您需要将可读深度缓冲区绑定到统一的sampler2D。然后:

  • 在当前屏幕位置采样深度缓冲区
  • 计算sceneDepth - currDepth,其中currDepth是您从vert着色器传入的变化,sceneDepth是您从深度缓冲区中采样的值
  • 应用一些数学但是你喜欢从这种差异中获得效果。对于一个非常粗略的示例,此处float effectAlpha = exp(-k * max(0.0, sceneDepth - currDepth)); k控制它逐渐淡出的速度。然后,您可以添加一些颜色,然后将其乘以effectAlpha

最终,关键在于您根据渲染几何体的深度与遮挡场景深度之间的差异来计算效果。因此,深度消退。'例如,使用类似的技术使水看起来平滑地淡入海岸线。

编辑:我只是掩饰了教程并注意到他也使用了菲涅耳效果。这是在掠过角度时给予一些亮点。如果你搜索菲涅尔效应GLSL,应该很容易找到源 - 菲涅耳在渲染中无处不在,特别是在基于物理的渲染中。基本的想法是,您将计算一个值为0的值,其中您的对象面临着'相机('面孔'表示法线矢量与相机方向对齐),1表示物体面向与相机垂直的方向。

实际上并没有显示菲涅耳在你发布的截图中非常明显(菲涅耳是一个非常轻微的效果,因为它大致像五度多项式一样衰落),所以你可以实现你的大部分只想深度消失。