备注:模型来源
模型来自:哔哩游戏,原神征集稿活动
无光照和漫反射对比图
描边大致分为三种
- 基于视角切线
- 基于几何的方式来描边(shell method)
- 法线外扩
- z值便宜(z-bias)
- 基于后处理(图像处理的方式)描边
基于视角切线
当模型的表面和观察视线,越趋向垂直,则越能表现出是是模型的边缘,通过公式
给定一个系数T
当点积大于系数则认为是1,模拟成视线方向和法线是同方向,让画面更干净,不会因为NdotV变得类似于漫反射一样的黑白过渡体积感
当点积小于系数则将点积进行一个pow操作,让点积的结果更加明显(注:NdoV点积结果是一个-1~1之间的值)
优点
- 很容易实现
缺点
- 线宽不一致,有粗有细
基于几何的方式来描边(shell method)
这类描边方式是讲一个单独的几何体额外绘制,原理和实现方式都比较简单
法线外扩
- 在正常绘制完模型(PASS1)
- 用正面剔除再绘制一次(PASS2)
- 在vs中,将顶点沿着法线方向扩张一点点距离
- 通过fs中用纯色输出
优点
- 很容易实现
缺点
需要两个Pass,但是如果管线支持
Early-Z
技术,可以很大的减少overdraw
消耗如果遇到Cube这种法线膨胀,会遇到gap缝隙(六个面各自沿着自己的方向扩张,面和面之间不连续)
z值偏移(z-bias)
- 在正常绘制完模型(PASS1)
- 用正面剔除再绘制一次(PASS2)
在vs中,将顶点z值稍微往前(观察坐标系)偏移一点点【靠近摄像机】
通过fs中用纯色输出
优点
- 很容易实现
缺点
需要两个Pass,但是如果管线支持
Early-Z
技术,可以很大的减少overdraw
消耗如果一个面正好垂直偏移方向,会整个面偏移出来绘制成纯色
基于图像处理的方式(后处理)描边
https://en.wikipedia.org/wiki/Sobel_operator
https://en.wikipedia.org/wiki/Edge_detection
这种实现方式更接近于边缘的概念,通过卷积查找在深度、法线中不连续的位置
因此获取边缘只需要找到法线贴图和深度贴图即可
- 前向渲染需要通过后处理
- 延迟渲染法线和深度信息已经在GBuffer中
优点
- 描边的线宽一致
缺点
- 需要额外的法线和深度信息