本文为初步入门学到的一些东西,并且由脑图转换而来,所以大多只是列一下这个知识点。
日式卡渲技术要点
描边
z-bias法(一般不用)
将顶点在观察空间的坐标偏移一定bias
法线外扩/翻转法线/Back Facing(常用)
- 正常着色
- 延法线外扩,剔除前面着色
- 保证拉近屏幕描边粗度不变化(以下任选一种)
- 使用NDC空间的距离进行外扩,ndc坐标是方形空间,还需要计算屏幕宽高比
- 正常使用顶点坐标外扩,但对z坐标进行修改
- 使用屏幕空间坐标外扩,和ndc类似
- 正方体使用这个描边会不连续,原因是顶点法线都垂直于面,延展开就分离了。可以将顶点法线平均保存在切线信息中,然后再用切线信息来外扩。(但如果像采样法线贴图、各向异性高光等需要用到切线信息,就要另做打算了)
- 如果要用到切线信息,可以存在uv8或顶点色,但是骨骼动画不会跟着变,所以需要存切线空间的,使用时再变换一次世界空间
- 还可以利用顶点色写入描边消隐和描边粗细,主要是有些部分美术可能不希望有描边,以及描边的粗细不要一致。虽然常见的是使用贴图,但这也是一个优化的思路,是为了排除像素精度带来的影响。因为采样极度依赖于分辨率,除非是超高分辨率,否则在特写镜头下很容易出现锯齿,而使用顶点属性则会根据屏幕分辨率来插值,达到更清晰的表现。
- 保证拉近屏幕描边粗度不变化(以下任选一种)
- 背面深度比前面深,所以不用担心遮挡问题,后渲染描边,可以利用深度测试去除大部分重复,增加效率
后处理描边
方案:
- Sobel算子
- Laplace算子
缺点:
- 无法控制描边或者说很难像外扩描边一样精细的控制描边效果,同时还会把内描边也检测出来
内描边
- 本村线
- 表现衣服上的褶皱等折痕
- 由美术制作贴图
- 为了防锯齿,uv会特殊处理(只有横竖的uv),制作比较麻烦
- 但会扭曲贴图上的文字和花纹,可以用贴花加上
- 后处理内描边
- 二之国分享
- 可能是美术标记,然后后处理描上,具体还要去了解···
- 基于SDF的内描边抗锯齿
着色
漫反射
- PBR
- 主要是为了展示更多的材质效果
- 常用于建筑物渲染
- 一般会将PBR效果降阶使用,或者和赛璐璐/Ramp等技术混合使用
- Ramp
- 普通的是一维,使用兰伯特计算去采样
- 实现类似菲涅尔现象的卡通渲染,可以用二维ramp,第二维是法线与视角方向相关(类似菲涅尔计算)
- 原神用的是5维,并且区分昼夜。使用哪一维数据由ILM图a通道决定
- CelShading
- 赛璐璐风格,代表作《罪恶装备》
- CellBandsShading
- Tone Based Shading
- 多层叠加
- Diffuse ramp贴图和Specular ramp有点像真实皮肤渲染用的预积分LUT贴图。猜测借此来表现出卡通角色皮肤的次表面散射效果
高光
常用头发高光
- 各向异性(这里以常用的Kajiya-Kay算法为例)
- 将头发看作圆柱体
- 一个像素可以看作很短的圆柱体–圆
- 用副切线ToH推导法线NoH
- 为什么不直接用法线:
- 个人理解是平常像素可能表达的是物体的一小块,法线是确定的。
- 这里一个像素可能表达了一小段头发,类似圆,法线是不确定的(各向异性),同理切线也不确定,但是副切线是确定的
- H离N越近,就说明离T越远
- 只要看上去能对那就是对的,所以唯一我们能算出来NdotH的时候只能是NHT处于同一平面,画图得三角函数关系
1
2
3float dotTH = dot(T, H);
float sinTH = sqrt(1.0 - dotTH \* dotTH);
NoH = sinTH
- 为什么不直接用法线:
- 法线+高光控制贴图(ilm)实现天使环
金属/非金属高光(remap)
- 基于Blinn-Phong,使用ILM图来控制高光范围和强度
- 金属部分高光可以结合Matcap贴图补充反射效果
PBR_GGX
Blinn_Phong
阴影
- 自带阴影方案(直接用会比较丑,依赖模型)
- 基于深度阴影–2d额发阴影
- 二值化阴影
- 脸部距离场阴影(伦勃朗光)
- 细节加强
- 阴影残留
- 阴影色调分离
边缘光
基于菲涅尔
- NdotV表示的是世界空间法线和视线的点积,反应的是从当前视线看去,像素点处于边缘的可能性
- 需要遮罩图屏蔽部分不想亮的(在一些有平面的物体,当平面和视线接近垂直的时候,会导致整个平面都有边缘光。这会让一些不该有边缘光的地方出现边缘光)
基于深度图
- 需要屏幕深度图
- 采样深度贴图获得当前深度,然后沿着一个特定的方向偏移屏幕空间的深度贴图uv坐标,再采样一个偏移后的深度。对比这2个深度,如果超出一定的阈值,将差值转化为深度边缘光强度
- 宽度比较统一
眼睛
贴图法
最简单省事的就是贴图,最多一层baseMap和一层高光足够了。放在高品质游戏里难免有点敷衍
新樱花大战中的做法比较复杂。眼睛的建模实际是两层,外层是向外凸的半透明层,用来绘制高光和反射,表示人眼的角膜;内层微微内凹,表示人眼的虹膜与中心的瞳孔。
- C:Albedo Map,基本贴图,表现出人眼的虹膜效果。
- D:对基本贴图的加算图
- E:高光图,也是通过加法计算,会通过UV动画进行移动
- F:环境反射图
视差
模拟瞳孔
反深度睫毛/眉毛
- 因为一般会被丢弃
- 利用深度测试,绘制两次法
- 使用RenderQueue按头发-脸-内眉毛-外眉毛的顺序绘制,眉毛绘制两遍
- 第一个用ZTest LEqual绘制没被头发挡住的眉毛,第二个用ZTest GEqual绘制盖在头发上的眉毛
- 眉毛的计算量并不多,这种做法会更省一点
- 模板测试
- 不过这样会多用一张模板贴图,在手机上对带宽不友好。
- 利用深度测试,绘制两次法
面部修正
- 修改面部法线
- 使用mask贴图
- 或使用顶点色通道
- 如果使用了sdf面部阴影,一般就不用面部修正?
Bloom
- 和PBR常见bloom不同,需要手动控制哪里需要bloom
- 遮罩纹理
- 利用a通道,适合不透明物体,如果要半透明,就要用双pass保存a了
多光源加权
效果展示
参考文章
- Unity下的日式卡通渲染实现-着色篇(一)
- Unity下的日式卡通渲染实现-阴影篇(二)
- GitHub-FernNPR,b站介绍视频,需要把里面提到的关键点原理搞懂
- 从0开始的卡通渲染
- 日式卡通渲染
- 卡通渲染技术总结
- 原神角色渲染
- SDF面部阴影图生成
- 基于HDRP的卡通渲染
- 顶点色ag通道存平滑法线的方案,评论区提出可以存偏移量精度更高
- 引擎中画顶点色工具
- 大佬博客
- 卡渲技术总结
- MatCap纹理
- 因为Matcap是非完全物理的,属于trick,使用的时候要格外的小心,避免对游戏整体的PBR环境有过大的影响
- 用在冰面等材质低成本添加cubemap反射的效果
- 角色在暗的地方整体亮度和高光强度都不够,适当使用matcap加强下表现