【问题标题】:Outline effects in OpenGLOpenGL 中的轮廓效果
【发布时间】:2012-10-16 22:06:01
【问题描述】:

在 OpenGL 中,我可以通过正常绘制对象来勾勒对象轮廓,然后使用模板缓冲区再次将其绘制为线框,这样原始对象就不会被覆盖。但是,这会导致轮廓只有一种纯色。

在这张图片中,生物轮廓的像素似乎越远离它们所描绘的生物,就越透明。如何使用 OpenGL 实现类似的效果?

【问题讨论】:

    标签: opengl graphics 3d glsl


    【解决方案1】:

    我迟到了答案,但我试图实现同样的目标,并认为我会分享我正在使用的解决方案。

    使用不那么复杂的着色器,可以在单个绘制操作中实现类似的效果。

    在片段着色器中,您将根据闪电和纹理计算片段的颜色,为您提供未突出显示的颜色“colorA”。

    您的第二种颜色是轮廓颜色“colorB”。

    你应该得到片段到相机向量,对其进行归一化,然后得到这个向量与片段法线的点积。

    片段到相机向量只是片段在眼睛空间中的位置的倒数。

    那么片段的颜色就是:

    float CameraFacingPercentage = dot(v_fragmentToCamera, v_Normal);
    gl_FragColor = ColorA * CameraFacingPercentage + ColorB * (1 - FacingCameraPercentage);
    

    这是基本概念,但您必须尝试使用​​或多或少的轮廓颜色。此外,模型的凹面部分也会突出显示,但问题中发布的图片也是如此。

    【讨论】:

      【解决方案2】:

      他们没有为此使用线框。我猜它与着色器密切相关并且需要这个:

      1. 将对象渲染到模板缓冲区
      2. 在应用模糊时使用选择的颜色渲染模板缓冲区
      3. 在其上渲染模型

      【讨论】:

      • 所以我们用纯色将对象绘制到纹理上,然后使用模糊着色器在屏幕上绘制该纹理?
      • 是的,但这可能不是唯一的方法。
      • 这基本上就是我在制作的标题上的做法,尽管它对我们来说速度很慢。在采用这种方法之前,请考虑一下屏幕的多少部分将包含您的大纲——有更便宜的效果可以用来传达“这个模型被突出显示”。在现代标题上,您可能没有多余的填充率。
      • 为什么不通过一个顶点着色器来做呢
      【解决方案3】:

      使用 dotprod(view,normal) 在 GLSL 着色器中检测边缘

      http://en.wikibooks.org/wiki/GLSL_Programming/Unity/Toon_Shading#Outlines

      【讨论】:

      • 请注意,此技术将突出显示所有可见的“边缘”,而不仅仅是轮廓。可能是可取的,也可能不是。
      【解决方案4】:

      据我所见,屏幕上的效果很短,许多“边缘”效果不是纯粹的边缘,就像漫画轮廓一样。大多数情况下,你有一个通道是你正常渲染对象,然后一个通道只有几何体(没有纹理)和一个 GLSL 着色器。在片段着色器中,法线被采用并且该法线垂直于您为对象着色的相机矢量。然后通过包含接近完美垂直的区域来平滑效果。

      我将不得不查找确切的数学,但我认为如果您将相机矢量与法线相乘,您会得到“垂直度”的量。然后你可以通过像 exp 这样的函数来获得偏向 1 的值。

      所以(不保证正确):

      exp(dot(vec3(0, 0, 1), normal));
      

      (注意:一切都在屏幕空间中。)

      【讨论】:

        猜你喜欢
        • 2011-06-22
        • 2019-05-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-10-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多