卡通渲染NPR-描边篇

备注:模型来源

模型来自:哔哩游戏,原神征集稿活动

http://ys.biligame.com/gczj/

http://ys.biligame.com/pjdkx/

无光照和漫反射对比图

p1

描边大致分为三种

  1. 基于视角切线
  2. 基于几何的方式来描边(shell method)
    • 法线外扩
    • z值便宜(z-bias)
  3. 基于后处理(图像处理的方式)描边

基于视角切线

p2

当模型的表面和观察视线,越趋向垂直,则越能表现出是是模型的边缘,通过公式

得到视线和法线的点积

给定一个系数T

当点积大于系数则认为是1,模拟成视线方向和法线是同方向,让画面更干净,不会因为NdotV变得类似于漫反射一样的黑白过渡体积感

当点积小于系数则将点积进行一个pow操作,让点积的结果更加明显(注:NdoV点积结果是一个-1~1之间的值)

优点

  • 很容易实现

缺点

  • 线宽不一致,有粗有细

基于几何的方式来描边(shell method)

这类描边方式是讲一个单独的几何体额外绘制,原理和实现方式都比较简单

法线外扩

p3
  1. 在正常绘制完模型(PASS1)
  2. 正面剔除再绘制一次(PASS2)
    1. 在vs中,将顶点沿着法线方向扩张一点点距离
    2. 通过fs中用纯色输出

优点

  • 很容易实现

缺点

  • 需要两个Pass,但是如果管线支持Early-Z技术,可以很大的减少overdraw消耗

  • 如果遇到Cube这种法线膨胀,会遇到gap缝隙(六个面各自沿着自己的方向扩张,面和面之间不连续)

z值偏移(z-bias)

p4
  1. 在正常绘制完模型(PASS1)
  2. 正面剔除再绘制一次(PASS2)
    1. 在vs中,将顶点z值稍微往前(观察坐标系)偏移一点点【靠近摄像机】

    2. 通过fs中用纯色输出

优点

  • 很容易实现

缺点

  • 需要两个Pass,但是如果管线支持Early-Z技术,可以很大的减少overdraw消耗

  • 如果一个面正好垂直偏移方向,会整个面偏移出来绘制成纯色

基于图像处理的方式(后处理)描边

p5

https://en.wikipedia.org/wiki/Sobel_operator

https://en.wikipedia.org/wiki/Edge_detection

这种实现方式更接近于边缘的概念,通过卷积查找在深度、法线中不连续的位置

因此获取边缘只需要找到法线贴图和深度贴图即可

  • 前向渲染需要通过后处理
  • 延迟渲染法线和深度信息已经在GBuffer中

优点

  • 描边的线宽一致

缺点

  • 需要额外的法线和深度信息