线宽可变的卡通/透明阴影?


15

我看到一些进行cel着色的广泛方法:

  1. 具有翻转法线的模型的复制和放大(对我而言不是一种选择)
  2. Sobel滤波器/片段着色器进行边缘检测的方法
  3. 模板缓冲区方法进行边缘检测
  4. 用于计算面法线和边缘法线的几何(或顶点)着色器方法

我是否假设以几何为中心的方法也可以最大程度地控制照明和线条粗细,这是正确的吗?对于可能会看到山的轮廓线逐渐合并成平原的地形?

如果我不需要地形表面的像素照明怎么办?(而且我可能不会,因为我计划使用基于单元的基于顶点或基于纹理贴图的照明/阴影。)那么我是否会更好地坚持使用几何类型方法,或者改为使用屏幕空间/片段方法?使事情更简单?如果是这样,我怎么会得到山上的“墨” 网的剪影,而不是只有整个网格(的轮廓与轮廓内没有“墨水”的细节?(AKA 暗示的轮廓折痕)。

最后,是否可以使用几何着色器廉价地模拟翻转法线方法?我对此的担心是,我当然可以复制每个单个顶点并相应地缩放它们,但是我将如何处理翻转法线和片段着色器中的不同着色?

我想要的-在轮廓内插入线来改变线的粗细...

在此处输入图片说明

我不要...

在此处输入图片说明


编辑:进一步的研究发现了以下...

由于我在地形上拥有大量顶点,因此即使考虑基于距离的LoD,由于所有对象的复制和缩放都涉及巨大的计算复杂性,因此无论是基于翻转法线还是基于几何着色器的方法(即使使用平截头体剔除)都不是明智的选择。上传的顶点。

考虑到我不需要在地形表面上以纯色阴影的形式进行逐像素照明,因此考虑基于面部法线的方法(否则需要正确的表面照明)也变得不太谨慎计算起来自然很昂贵。但是,他们确实提供了最好的控制权。例如,使用“艺术”笔触为边缘着色的能力:漂亮,但又不能在大规模复杂的游戏环境中真正实现。

我宁愿避免使用模板缓冲区,因为我希望在着色器中完成所有工作。(上面带有红色轮廓的示例是使用模板缓冲区-旧学校完成的。)

这样就留下了片段着色器的图像空间方法。计算复杂度降低为片段的数量,而不是顶点的数量(在我的情况下,这比几何着色器中的操作要少10-100倍)。为了生成一个g缓冲区(包括一个普通缓冲区和一个可选的深度缓冲区),需要多次渲染渲染,我们可以将不连续性滤镜(例如Sobel运算符)应用到该缓冲区。深度不连续性使轮廓和折痕产生暗示。我唯一的疑问是无法对墨迹边缘宽度进行更好的控制,尽管使用片段着色器中的正确算法,我相信这是可能的。

因此,现在的问题变得更加具体:我如何精确地在片段着色器中获得可变的边缘宽度,尤其是在外部轮廓上?


线宽的变化是几何方法的特征。无法以其他任何方式有效地获取它。既然您想要那样,我不认为像素着色器是“更有效的方法”:要搜索的像素数=(line_thickness * 2 +1)^ 2-1。这基本上意味着您的后期处理着色器如果最大,速度会慢很多(猜测:10倍)。线宽等于2。只需取消预判断并尝试使用几何着色器方法。
snake5

@ snake5老实说,我建议我在GS中每次渲染更新都要处理1.5亿个顶点(使用视图剔除时要处理约2500万个)?我不是真的买那个,但是谢谢你的投入。回到我上面所说的关于顶点数和复杂度的内容。即使使用10倍的图形,片段着色器也将至少绘制均匀的图形,并且可能做得更好。
工程师

1280x720,2500万个顶点(线性读取/写入)与2300万个纹理样本(而不是高速缓存的内存读取+渲染目标数据的解压缩)相对。顺便说一下,限制/减少顶点数量要容易得多。尤其是在如今,大型显示器(1920x1080 +)和多显示器设置变得非常流行。
snake5

使用与生成红色轮廓的算法相同的算法,然后根据其深度细化/生长线又如何呢?
Ali1S232

@Gajoo,正如我在问题中所说的,这不仅是轮廓。注意第一个图像中女孩肩膀后面的侵入线。这些是法线翻转法的功能,并充当暗示性的轮廓/折痕。我也一样
工程师

Answers:


4

我决定通过深度缓冲区的不连续过滤使用片段着色器方法。原因如下:

  1. 由于巨大的视距,即使使用网格LoD,世界顶点计数也非常非常高。
  2. 我正在执行许多其他片段着色器操作,例如DoF模糊,它们可以在同一遍操作中受益于相同的结构(盒子或高斯采样/过滤)。

经过测试,我会说,出于复杂性原因,在以后的项目中,我会改用基于几何的方法。原因是(如评论中的其他建议),片段着色器进行边缘检测的方法可能计算量很大,尤其是在DoF实现中,其中混淆半径的圆度以及每个片段的样本数可能很高。幸运的是,轮廓着色器不必担心。


我认为在法线不平坦的情况下使用法线不连续会给您更好的结果。您可以通过将样本分开得更远来改变线宽。
Grieverheart

@Grieverheart这是公认的答案,因为我使用的方法效果很好。谢谢。
工程师

0

如果可以使用后效应,实际上有一个非常简单的通用解决方案。很棒的是,您的多数量多高无关紧要。当两个相邻像素之间的对比度高于阈值时,将深度图渲染为灰度,然后以所需的线条颜色创建一个点。您可以根据所渲染图像的对比度和/或光线级别来增大点。

我在2000/2001年发明了toonShader算法,甚至在那个创建此解决方案的法国人之前。矿山是基于实际的材料几何形状。然后,基本上有两种方法可以执行此操作:1.查看法线,如果法线连接到一条线上的两个平面背对摄像机并朝向相机,则渲染该线,然后可以使用深度,照明等作为线深度的提示。2.查看渲染的几何体(因此在透视变换之后)以每个线段为例,如果连接平面的顶点在该线段的同一侧,则渲染线。然后,您可以对线宽进行与方法1。3.您可以组合使用这三种技术,但是我提到了第一种,因为您指出了一个巨大的多边形数。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.