OpenGL中的轮廓效果

OpenGL中的轮廓效果,opengl,graphics,3d,glsl,Opengl,Graphics,3d,Glsl,在OpenGL中,我可以通过正常绘制对象来勾勒对象的轮廓,然后使用模具缓冲区将其再次绘制为线框,这样就不会绘制原始对象。但是,这会生成具有一种纯色的轮廓 在这张图像中,生物轮廓的像素看起来越是远离其轮廓的生物就越透明。如何使用OpenGL实现类似效果?他们没有为此使用线框。我猜它与着色器密切相关,需要: 将对象渲染到模具缓冲区 应用模糊时使用所选颜色渲染模具缓冲区 在它上面渲染模型 使用dotprod(视图,法线)检测GLSL着色器中的边 在我看来,屏幕上的效果很短,许多“边缘”效果并不像漫画

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


在这张图像中,生物轮廓的像素看起来越是远离其轮廓的生物就越透明。如何使用OpenGL实现类似效果?

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

  • 将对象渲染到模具缓冲区
  • 应用模糊时使用所选颜色渲染模具缓冲区
  • 在它上面渲染模型

  • 使用dotprod(视图,法线)检测GLSL着色器中的边


    在我看来,屏幕上的效果很短,许多“边缘”效果并不像漫画大纲中那样是纯粹的边缘。主要完成的是,如果您正常渲染对象,则只有一个过程,然后是仅使用几何体(无纹理)和GLSL着色器的过程。在片段着色器中,将获取法线,该法线垂直于为对象着色的摄影机向量。然后通过包含接近完美垂直的区域来平滑效果

    我必须查精确的数学,但我认为如果你取相机向量和法线的点积,你就得到了“垂直度”。然后,您可以运行exp之类的函数来获得对1的偏差

    因此(不保证其正确性):


    (注意:所有内容都在屏幕空间中。)

    我回答得晚了,但我正试图实现同样的目标,并想与大家分享我正在使用的解决方案

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

    在片段着色器中,您将根据闪电和纹理计算片段的颜色,从而获得未高亮显示的颜色“colorA”

    第二种颜色是轮廓颜色“colorB”

    您应该获得片段到摄影机向量,将其规格化,然后获得该向量与片段法线的点积

    片段到摄影机的矢量只是片段在眼睛空间中位置的倒数

    碎片的颜色为:

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

    这是一个基本的想法,但是你必须要有更多或更少的轮廓颜色。此外,模型的凹面部分也将高亮显示,但问题中发布的图像也是如此。

    因此,我们使用纯色将对象绘制到纹理,然后使用模糊着色器在屏幕上绘制该纹理?是,但这可能不是唯一的方法。这就是我写的标题的基本方式,尽管对我们来说速度有点慢。考虑在执行这个方法之前,屏幕的多少会包含你的轮廓——有更便宜的效果可以用来传达“这个模型被高亮显示”。在现代标题上,你可能没有多余的填充率。为什么不使用顶点着色器,在法线方向上按偏移量推动顶点,并将其用作轮廓(平面渲染),然后渲染顶部颜色请注意,此技术将高亮显示所有可见的“边”,而不仅仅是轮廓。可能需要,也可能不需要。
    float CameraFacingPercentage = dot(v_fragmentToCamera, v_Normal);
    gl_FragColor = ColorA * CameraFacingPercentage + ColorB * (1 - FacingCameraPercentage);