Origin
zhuanlan.zhihu.com
Tags
风格化
渲染
流程规范
技术详解
项目
收藏夹
创建时间
收藏类型
Cubox 深度链接
更新时间
原链接
描述

脸部法线修正

【图片已被建议修改,请脑补】
这是我很喜欢用来当例子的一个对比图。
可以看到,绘制的人体和真实人体在明暗关系上还是有很大相似性的,但脸则是例外。
和身体不同,二次元的脸几乎和现实已经没有任何关系了,试图构筑一个真实的光照模型是很困难的。
外部轮廓方面,脸模的设计并非特别困难,通过脸的外轮廓构建正视的曲线,通过鼻梁构建侧视的曲线,调整其他部分让两者有一个平滑的过渡,同时兼顾眼睛和眉毛的位置,就能制作出这样一个脸模…… 但它仅仅能够保证轮廓正确而已。
(眼睛和眉毛的位置还可以通过 blendshape 来进一步调整侧面时的位置,但目前看,除非遇到特殊画风,这个做法收益很低,因为眼睛眉毛的位置用普通做法已经足够符合了。https://twitter.com/rukikuri/status/1245080903757389824)
但我们还需要光影,也就需要法线,这样为了形状凑出来的模型 (往往具有奇怪的鼻子形状) 的法线自然是一团糟需要重设。
而调整…… 也只能找几个固定的角度按要求调好,并保证它们之间的过渡不违和。
notion image
可以看到,脸的光影并非一般人所想是一条竖线,而是在眼下存在一个三角区域 (其实还有其他的一些细节这张图没实现)。
这里就有一个问题。如果我们打算调整顶点法线来实现这个效果,就必须在这里布置特殊排线,否则法线的变化频度会不够,也就需要下面的排线 (ggxx 第一次使用的)。
notion image
但即使做了,想要实现上图良好的过度效果依然比较困难,因为调整法线依然受到了排线的限制,修改时的自由度太低了。
并且修改过的法线,一旦改模就会丢失。
所以相比之下,用法线图的方式显然要简便得多。
事实上,崩坏 / 原神就是用的纹理调法线的做法 (但只处理了 x 方向),实际是一种物体空间法线贴图,需要传入一个脸部朝向。
下面是一个在 sp 下绘制这种法线图的方案。
notion image
这样也可以继续使用普通的眼口模型了。
注意,这张图并不是普通的切线空间法线图,而是物体空间的,所以不能用通常的方法显示。你也可以把这张图转换回切线空间……
但物体空间也有个好处,就是表情口型导致的顶点变更不会再影响到光照分布了,而这正是一般二次元渲染希望有的结果。如果确实在个别情况下需要光照随表情改变,也可以增加另一张脸部法线图做插值,这样自由度和可控性都会更好。
当然理论上让 blendshape 不修改法线也可以有这个效果,但具体怎么操作不太清楚。

正面光照

调整了法线,光照的问题就解决了吗?
并没有。调了法线只是让脸不至于整个是崩的,但是一些侧面的角度,其实依然不美。
过场中可以根据情况设置光源避免出现这个情况,但在实际游戏中,总会在一些时候被丑到。
所以,就有了下面这种放弃治疗的做法:
光照方向与场景无关,只与角色朝向和视角有关。
光照首先优先视角方向,随着角色朝向而偏移,但不能超过 30 度夹角。
当光照转到视角背面时,对光照方向做一个 tween,绕到背后继续这个逻辑。
(懒得录视频,可以看看战双人物界面的处理)
这样做最大的问题就是和实际光照方向无关了,所以考虑把光源方向也插入到上面的逻辑来?
但毕竟大部分的场景都不存在强光源,而这样的处理方法,确实能解决大部分的问题。人眼对光照方向的敏感度很低,只要别搞太多的旋转镜头,一般人甚至永远都无法发现这个问题。
多人的战斗场景最好和角色朝向也无关,这样可以让整个场景的角色共有同一个光照方向,避免在同屏产生视觉矛盾。
注意这毕竟是个放弃治疗的办法,至于不放弃治疗有没有救?我不知道,我打算放弃治疗。

额发投影

notion image
而固定成正面光照同时还把令人恼火的额发投影解决了。大家应该发现很多游戏明明角色各种地方都有投影,偏偏隐藏了额发投影。它们就是为了避免出现图 1 的结果(也可能是批量调整 bias 的副产物)。
当然,图 1 丑还跟鼻子,脸产生了多余的自投影有关,这些需要单独设置 bias 来消除。但即使消除了,其实还是丑。
但只要使用正面光照,即使不调 bias 这些问题也都不存在了。
正面光照的问题就是会让投影很难出现,所以在适当范围内做一点偏移,效果才比较好 (这就是上面让光照方向也和角色朝向有关的原因)。
但额发直接投影效果其实是不对的。从物理角度讲,额发投影除了投影还有 ao 的贡献。美观角度讲,投影是为了表达物体的空间关系,不管该不该有,需要的时候都该有。
具体的问题如下图。
notion image
不动的头发,我们可以绘制 ao 图让侧面的额外投影出现。
如果两边都是活动的就不行了。虽然也可以用法线扩展投影物体大小的方式来扩大范围,但这样还不如再创建一个专门用于投影的模型。
这样也能一并解决长头发隐藏投影以及齐刘海拉平投影的问题。
notion image
实时 ao 的话…… 则在于精度,没有 dxr 恐怕困难,很容易出现扭曲和抖动。再说这玩意好多时候表现也一点都不 ao。
此外,虽然之前说人物光照要固定到视角正面,自投影也需要固定在视角正面,但人物对地面的投影自然不可能这样变来变去,只能固定在世界空间里。
因此,我们必须使用两个 shadowmap,分别处理自投影和对外投影,或者每个人物(乃至每个部位)使用独立 shadowmap(用图集 shadowmap 的方式实现)。
由于自投影的投影区域大小可以控制得很精确,后者方案效率上会更好一些。

头发高光

写实渲染的头发渲染一般用的是 KK,就是那个各向异性扰动贴图。
但写实渲染的各向异性其实接近于纯随机,并不需要手绘。所以头发也可以选择不拉直 UV,而采用 flowmap 的方式实现。
而卡通渲染,这个高光的形状既不物理也不重复,无法使用 flowmap。如果要做的话,必须把 UV 拉直然后小心地手绘高光偏移和粗糙度来凑出这个高光形状。(不拉直 UV 会出现贴图精度不够导致的锯齿)
非要说的话,虽然非常麻烦,也不是做不到。
这个做法做出来的高光带一旦角度改变很容易就会乱掉,所以需要限死 x 角度避免光带倾斜,并且限制 y 轴范围避免光带移动到不合适的范围。
画出这张图这实在太麻烦了,在头发运动的时候效果也很糟糕。
另一种方式就是放弃光照角度的正确性。其中最简单的做法,就是使用固定贴图。GGXX 的头发高光就基本是固定贴图。
但完全固定的贴图的贴图感太明显了,为了回避这点可以在视角变化时加一点变化。
虽然想让光带上下移动比较麻烦,但想要光带缩小就只需要一张阈值图,然后根据视角来决定阈值,让中间的光带较宽,两侧的光带较窄,这样人物运动的时候起码这个光带并不是完全固定的,也符合正面光高光给人的映像。
(注意这个方法不一定只用在头发上,也可以用在任何,希望产生固定,边缘锐利的高光,但又不希望始终没有变化的部分,诸如胸反光,肌肉高光,面颊、嘴唇光点。)
但这种设计和固定光带一样,依然存在一个问题。光带在正视的时候看起来是最美观的,但是在自由视角,就存在玩家把镜头转到头顶上的问题。在那个视角上头顶光带会在头的周围变成一个圈,非常违和,也很难看。
而现在许多游戏的解决方法就是:压根不让你把镜头 y 轴拉到那个角度去。
但这终归是不好的。
notion image
子弹少女用了一个特别的方法:在 y 轴角度到达一个阈值后,会把这个光带渐渐裁掉。但这样做非常重要的一点是,裁掉光带后必须在头顶位置显示一个新的光带(图中的中心散射光带),否则从用户视觉角度,他们会觉得高光突然消失了,从而使得头发的光照特性突然改变了。
因为这其实是一个近似正面光照的模型,所以对着镜头的正面是应该有反光的。
子弹少女的处理方法虽然不错,但这个头顶光带对画风是有一定要求的,并不是所有的画风都能兼容。而除此之外的方案暂时我就不知道了。那个时候,恐怕你就只能选择限制摄像机。
此外,这个高光是头发材质特性的一部分,在不使用正面光照的时候,暗部的光带也不应该隐藏,而只能变暗(就和这个光照是画在固有色里的感觉差不多)。这点要额外注意。

光照颜色

二值化光实际上是在固定好的暗部颜色和亮部颜色之间插值,这种做法和普通的颜色光照模型是冲突的。一般的做法是让暗部乘以环境光颜色,亮部乘以直接光颜色,多光源叠加时则使用亮部减去暗部后的差值进行叠加。
但既然现在都放弃主光源直接弄正面光照了,那这个光照的亮部颜色用哪个光的颜色呢?
也只能用环境光的吧?
简而言之,因为我们已经把光照方向用做其他用途了,在真正的光源方面,我们需要一个 “无方向光” 的概念。或者说,将光照颜色和光照方向分离。
直接光照,我们不再让光照方向和法线方向点乘,而是直接根据距离衰减减弱光照,并除 Pi 获得一个各方向光照的均值。
光照探针提供的间接光照,我们可以直接使用第一层 SH 的值(Unity 的做法是在获取 SH9 的时候传入 (0,0,0) 这个参数),它实际上就是各方向光的均值。
我们还可以在场景上布置一些碰撞体,进入碰撞的时候调整材质的亮度,因为探针布置起来挺麻烦的精度也不高,也不好处理进出时的突变。
这些光相加后,直接乘在颜色上,对暗部和亮部同时造成影响。
这样产生的光照和法线无关,只按光照距离衰减,是一个类似氛围光的东西,可以让人物融入到四周的环境中。在接近一个光源时,人物会渐渐染上光源的颜色。而在进入阴影时,整个人物会变黑。
虽然光照的方向特性完全没有了,起码不会让人物在场景里显得违和。
这算是个古法,在机能不足以处理方向光的时代,很常用。
事实上,现在不少游戏还就是这样搞的(包括战双),毕竟也没啥更好的办法。
而这个做法我觉得有个优化的手段:根据预定的光照方向将模型分为明暗两个角度,两部分分别计算半球均值获得颜色,这样光源在物体周围旋转的时候起码不会毫无变化,在光照较多的场景里多多少少能多一些动态变化,也能反应出背光和正光颜色的不同(边缘光也是一种背光)。
但没试,不知道实际效果如何。
notion image
动画中,方向光过渡大多利用分层调色实现,放在即时渲染里,就是在模型上虚构一个圆柱体,来生成上面的黑白渐变区域。脸和身体分别处理。
这个在剧情过场中必然是可行的,毕竟动画就这样做的。但是在自由视角的游戏里根据光源生成这个…… 就不知道会变成什么样了。
此外,这种过渡其实是类似 BlendNormal 的思路,由于原始法线过于高频,而卡通渲染需要简化的光照效果,所以或许可以通过在屏幕空间,以 depth 为界限大幅模糊 Normal 纹理来实现?
普通的模糊滤镜是不行的,就算可以,也得用特殊的做法。
我觉得线性调光的这种做法还是值得一试的,至少可以提高实时过场和动画的相似性。

多光源

此外,在攻击时产生光特效的时候,有必要在特效位置安置一个光源来照亮场景,这能显著提高画面观感。场景正常根据法线着色即可,人物…… 目前要不就是用这种无方向光的方法,要不就是额外附加一个二值化方向光(以及两者混合)。
这个真的有必要做,战双和后崩都已经加了这个了。
notion image
多光照会涉及到光照裁剪。但如果始终保持只有 1,2 个光源,裁不裁倒也无所谓,现在早不在乎多这点计算了。
(而 Buildin 会涉及多 PASS,性能不能接受,如果用 Buildin 请重新实现光照系统,可以退回到 LightMode Vertex,用 unity_LightColor,unity_LightPosition 获取最近的 8 个光源处理光照。可以的话,也可以转 URP,并帮 URP 实现尚未实现的功能)

Bloom

如果你觉得你建出来的模型很难看。开启后处理随便加个 Bloom,会有惊喜。
Bloom,尤其对动画风的渲染加成非常大。虽然 Bloom 一般会调的非常弱,弱到几乎看不出来,但是你加了就是比不加好看。这是一种很微妙的感受。
传统动画,Bloom 本来就是个非常重要的步骤。
notion image
但这个 Bloom 和写实渲染里普通的 HDR 还有些区别。普通的 HDR 是根据原像素 rgb 通道的最高值作为阈值来决定混合的模糊图的强度的,也就是越亮的部分发光程度越高。
但动画里,其实……Bloom 的系数和亮度关系并不是很大。
使用 PBR 的方式来处理 Bloom,很容易导致泛光部分发白。而我们需要的其实是一个带颜色的光晕。
notion image
所以我们需要向屏幕缓冲写入一个专门 Bloom 系数来控制 Bloom 强度,这样就可以让任何颜色的物体泛光了(但根据画风,一般也会参考颜色的亮度值,这样 Bloom 系数就只需要一个修正用的值而非贴图)
这里有两个方法,一个是 MRT,思路很简单,但需要额外申请一个 RGBA(RT 每次必须读取至少 32 位),但却只用了其中 8bit,太浪费了。
但假如你本来就要额外使用一个 RGBA(比如同时也想生成 normal),正好差 8bit 没用,放在这里就是白嫖。
另一个方法就是传统的写入 alpha 通道的做法。但这个做法在 AlphaBlend 的情况下,由于 Alpha 值也需要写入 Alpha 通道,就和 Bloom 系数冲突了。修正它的方法是使用双 PASS,一个专门写 RGB 通道,一个专门写 A 通道来解决这个问题。
这个方案暗黑 3 就在用,虽说这也和它出的早有关系。
后面崩三战双也在用……
选择哪个还是看具体需要。MRT 方案的问题是需要额外带宽,写 Alpha 通道的问题就是 Alpha Blend 需要额外 PASS(Additive 不需要)。如果你的游戏特效使用 Additive 较多,额外 PASS 就少,就越适合写 Alpha 的方案。而且即使是 Alpha Blend,如果你不在乎 Bloom 系数的准确性,AlphaBlend 物体大多也能堆叠到接近不透明,Bloom 系数也允许常态使用最高值 1…… 那特效不用第二个 PASS 修正也是可以的。
不修正,缺陷就是特效容易因为 Bloom 而过爆(但战双的过爆现象很少见,是不是修正的比较普遍就不知道了)
我们可以让 Bloom 系数影响程度降低,普通特效需要的 Bloom 就是 Bloom 系数的最高值。如果需要较大的 Bloom 强度,则通过在 HDR 范围调整颜色本身的亮度来控制(这样 Bloom 就会更加接近 PBR)…… 虽然束手束脚,应该也可以勉强达到我们的要求。
但我是不太希望用这么不稳定的实现。
MRT 的方案,还可以把深度写入没有作用的 Alpha 通道,这样深度特效就不需要 resolve depth,也不需要 pre-depth。正好不透明物体也不需要写入深度。
动画和游戏的 Bloom 还有一个重要的区别是:模糊图和原图的混合模式并不只有线性减淡 (Additive)。
如果像动画后期一样使用不同的混合模式,则有希望做出更接近动画的结果(上面视频最后加深的效果是通过叠加混合实现的)。这个还需要尝试和探索。
之前我们的方案,终究只是 PBR 的一个修正,还有很大修正空间。

面部细节

眼睛折射一类老黄历就不说了。二次元渲染的眼睛和嘴是不能用图的,因为它们在正面和侧面具有不同的轮廓。你必须对睫毛建模,至于眉毛…… 则看细致程度,严格来讲眉毛也和睫毛有类似的问题,但假如原画的眉毛只有一根细线就无所谓。
总之,不要想着用切换图片精灵的方法来做表情。为了质量还是要老老实实,和写实渲染一样去搞。
目前的游戏人物表情和口型都是用的 blendshape 而非骨骼,原因我不太明白。毕竟 blendshape 全无复用的可能,而脸部还是存在不少需要建模的部分。
这里就要提到一个叫 vroid 的软件,可以比较方便地生成和绘制二次元人物模型,生成后自带表情 blendshape。所以,如果能做一个工具把表情这个过程参数化,最后输出 blendshape 作为结果,将能大大提升铺量的效率。
(另外你也不知道他们到底是不是就是用这玩意儿做的,毕竟这玩意儿确实方便,输出结果又不是不能改)
其他的方法我就不知道了。
此外,崩坏将眼睛部分的脸部做了单独建模,估计是为了方便在特殊表情(比如 X.X)的时候更换眼睛模型。但我觉得,与其这样将 blendshape 撕裂开两部分,倒不如在特殊表情的时候直接把一个单独模型盖在原来的眼睛上面(原模型这部分下陷避免穿帮),这样不影响默认表情,想换哪就换哪也更加自由。
某些画风需要让眉毛乃至眼睛显示在头发上方,如果不生成单独模型,就需要在顶点上记录一个 clip 上 z 的偏移,但这样无法处理眼球的问题,而且在头发剧烈运动时依然可能穿帮。保险的方法是使用模板遮罩,先画眼睛部分再画头发,并让头发部分镂空,最后再画一次眼睛将遮罩清空避免影响到其他的人物。
不是很好操作,所以最好别有眼睛显示在头发上这样的需求。眉毛好办。

描边

其实…… 只追求效果,后处理描边才是终点,但可控性高的后处理描边成本太高了。
还是先把目光限定在 backface 描边上。
backface 描边必须要处理硬边的描边错误,Unity 下,利用资源自动处理脚本是最方便的方法。
notion image
这个方案是将经过调整的切线空间的描线方向储存进顶点色,frag 展开到世界空间后代替法线来扩边。
我的方案和他有点区别。我打算用三个颜色值表示方向,同时用颜色值的长度表示描线的粗细。最后还剩一个 alpha 通道,可以用来存储描边颜色 index,或者 clip Z 偏移。这个看情况吧。
除了硬边,描边还有一个必须处理的问题:部分内描线的隐藏。
按现在的做法,嘴,眼框在正面很容易显露出多余描线来,但侧面它们依然需要显示描线,所以不能直接缩小描线的宽度。
有两个方法,一个是刚才提到的调整 clip 空间的 z,让它稍微靠后绘制。在侧面的时候向后绘制也没区别,但视角处于正面的时候,靠后绘制会被后方的模型挡住,就成功隐藏了。这个做法很稳。
一个是插值切线和法线 (令法线偏向切线而变弱) 来作为描线方向。它也会让侧面描线比正面描线更容易出现,但过渡区域比上一个方法更平滑。而且还可以直接存进顶点色的 RGB,不需要额外储存。但它在隐藏正面描线的时候也会减弱侧面描线,操作没有 clipZ 那么“正交”,可能有些时候会消除不干净。
用来处理下巴到脖子那条线是比较好的,可以看到线条变细的过度。
有空间储存数据,两个都用是最好的。
大块物体的描边颜色通常一致,虽然是可以放到材质上,但如果将它放到顶点上并做一个全局的 colormap,所有物体的描边就都可以用同一个材质绘制。
color 的 a 通道被占用的话,可以将这个颜色索引放到某个 uv 上。
内描边有多种方案。我搞的那个距离场描线的主要目的是在缩放时保持描线宽度,和外描线保持相同观感。
但这需求吧…… 其实也没那么敏感,毕竟多了一张图呢。锯齿别的方法也能消除。
说到这里。
外描线请务必使用屏幕空间的方法,保持描线宽度不随缩放变化。因为…… 动画是这样的。
但这种做法容易导致远景描线粗短凌乱,所以有些游戏会允许过远的物体缩小描边宽度。
我觉得也可以用偏移 clipZ 的方法来隐藏远处人物的内部描线,只保留最外一圈的描线,这应该也可以解决问题。

运动模糊

PBR 的速度动态必然通过模糊来呈现…… 但卡通渲染,其实和模糊并不怎么兼容。
当然模糊也可以用,就是没那么兼容而已。
notion image
一般会将高速运动的模型临时换成一张透明图,特效化。
但其实也可以考虑用运动方向的顶点扰动来模拟,基本实现是这个:
这个案例实现的是瞬移特效。但这个做法,如果不变色,距离变短,持续时间变短到一两帧,仅仅是向移动的反方向做一点变形,是可以用来增加一般攻击动作的…… 怎么说呢,类似劲力的感觉?
实现它如果能取到顶点的速度信息会方便很多,但在 skinMesh 里,因为缺乏公开 API,想要获得这个信息必须用 BakeMesh,效率太低了。
而且为了不影响别的区域,最好有一个 Mask,限制这个效果只出现在指定的运动物体上(诸如运动的手臂,武器等等)。
反正也取不到速度图,直接从骨骼节点获得整个物体大概的速度和角速度,然后利用顶点上储存的 mask 信息,实现它也不失为一个方法,还可以通过角速度制作出拖影的弧线。

插画风和动画风

在动画风渲染作为主流的现在,试图引入插画的画风是很合理的想法。
notion image
如果希望不同光照下有动态的变化,就必须引入和光照,法线相关的工具,通常使用 Ramp 图,但也可以用公式部分代替。 之前米哈游 MMD 提供的方案本质是一种 3 张 Ramp 渲染的叠加,通过让每个像素 3 层 Ramp 混合时具有不同的深浅和色彩(通过贴图提供)来获得更多的自由度。而如果用公式代替 Ramp 图,公式参数也通过贴图提供,则每层的覆盖范围也可以调整,获得更加自由的结果。
但在实际游戏中,却基本看不到用这种方案制作的产品。
具体原因不明,可能是成本,也可能是这种方式制作的材质在光照变化时依然无法获得令人满意的兼容性。
摆在我们面前的,则有一条容易得多的道路:将光影直接画死在贴图上。
在无外部光源的空白场景内,这样制作的模型可以获得和原画非常高的相似度。
notion image
(可以使用两套 uv,其中一套按预定角度做好模型姿势,从屏幕方向生成一套 uv.,把原画贴上然后烘焙到正常的 uv 上。但这样做能省多少工时我是抱有疑问的)
当然,这是以无光照作为前提。一旦为了体现环境而加入光照,则必然会偏离原画的意图。但以一个足够好的原画作为基础,偏离后的结果也不会太难看。必然可行的光照模式是在衣服上附加一定 PBR 特性(尤其金属),也可以用视角方向的 MATCAP 提供更加自定义的结果,这也是目前很常见的做法。
notion image
在二值化光模型实在不适用时,完全去掉身体上的方向光照也不失为一个方案。毕竟固定视角的二值化光也已经失去了光照本身的特性,仅仅是一个勾勒身体立体感的方式,而且贴图的固定感也可以用外描边光解除。
但更合理的方式应当还是尽可能在两者之间寻找可以妥协的点,或者使用一个和二值化光照更加兼容的画风。固定贴图或许好看,终究还是缺乏灵动。
notion image
插画风格(尤其带光照的)的产品很少,这是一个很值得探索的点。

场景调色

场景就是另外一个问题。
首先我们要知道,什么样的场景是我们的目标。
notion image
notion image
可以看到,看上去比较像卡通的场景,都具有连续规则的色彩分布,而且三原色色带会相互错开。
因为通常灰度是连续的,表现出来的就是色彩的区域化,不同颜色会集中在特定的位置上,而不是互相嘈杂在一起。
因为色彩相互错开,灰色的部分不多,色彩饱和度也较高。
这确实是后期调色可以做到的。一般后期调色的做法就是明中暗分别偏向不同的颜色,最终就可以达到各个区域颜色近似,但是不同区域颜色又有区别的效果。
当然,将整个屏幕调成一种颜色也可以做到色彩调和,也是可以的,但色调就会变得比较单一。
但只要能达到目的,怎么做都行。
pbr 是很便利的,产出快,而且支持动态光。所以用 pbr 出场景然后后期调色确实是可行的。但这样做的效果是有限的,想要获得好的效果,还是要在最开始画贴图和布光的时候就弄好,给调色一个好的底子。
贴图自然尽量使用平整的色块,饱和度别太低,但同一物体的色彩数不宜过多差异不宜过大,否则很难获得好的色彩分布。
基于同样的原则,卡渲最好多使用颜色光,因为颜色光也可以做到让一个区域颜色近似,但不同区域颜色不同,并提高饱和度。物体的不同朝向被不同光着色,点光源补亮暗部避免细节丢失,如果色彩出现了不和谐,也可以用特定颜色光补足。
大家当然都希望直接用 pbr,然后用一次后期调色解决所有的问题。使用 pbr 没问题,但至少光还是要布的。
说白了就是回归 pbr 流程诞生前的古法。
材质方面,大概就只有一个暗部单独着色的方法可以用,但 lut 也可以做到让暗部并非纯黑的效果,所以这也不是必须的,但可以增加一个调整颜色的手段。
物体上各种不同的成分都需要能单独调色,比如反射,环境光。
调色最大的问题是不好控制。最好能像动画一样实现分层调色,并且每层还能使用 mask。不管是各层调色后合成还是画索引用多组 lut 都有一些效率问题…… 可能得放弃 lut 将调色参数写入 gbuffer(或者在 frag 上直接处理),然后用公式调色?
现实情况下,根据深度调色也早有案例。最终,我们想获得的都是一个平滑,且多彩的结果。
notion image
pbr 场景不适用于卡渲,最大的问题是 pbr 场景通常是低饱和度的,而卡渲人物一般是高饱和度的。两者直接结合凑不到一起。赛璐璐还是厚涂并没有那么重要,人物赛璐璐,场景是其他风格一直很常见。
所以要想办法提高场景的饱和度,上面所说的就是增加场景饱和度又不会导致难看的方法。饱和度高并不需要像动画那样色彩数多,而是要远离纯灰。实在不行染成纯蓝都可以做到这点,但画面的色彩层次完全没有了,所以,不要放弃治疗。
同时人物的饱和度也可以降低,但一般而言都很难让人接受。稍微低一点可以,但强行调到和 pbr 场景一样多半不行,太怪异了。
notion image
但低饱和度人物也不是完全不行。如果你的服侍设计以黑白为主,皮肤接近纯白,设计上让画面存在大量纯黑纯白,再点缀其他高饱和度纯色……
你以为我又在说战双,乃至明日方舟?
不,我说的是 BRS。
这个设计不光是为了酷。它就是在处理颜色问题上有很大的优势,最终就容易做得好看。
而这个风格是否讨喜就看人了。但不管讨不讨喜,没有颜色就不需要调色,制作难度低是肯定的。在审美疲劳到来之前,其实是一个很好的选择。

手绘光照图

布光,其实类似于一种用光源作为笔触来绘制场景的手段。
它是有精度的限制的。
虽然似乎一提到手绘光照就像是在为难美术,但如果对场景细节的质量要求高到了一定程度,硬要用布光来调细节,可能还不如手绘光照图来得快。
notion image
notion image
像三位一体这样的 3d 游戏,在我看仅使用光照调成这样是不可能的。毕竟看上去就像是手绘出来的 2d 游戏,放弃手绘又怎么做得出来?
首先,小场景手绘光照还是比较简单的,直接在三维软件里烘焙,然后叠图层手修就好了 (不管是 sp 还是别的什么)。现在事实上也是这样做的。
但大场景内,包含了大量需要重用的物体,就需要游戏引擎来布置场景。那么,光照图的 uv 分布就成了个问题。引擎会重置 uv,你总不成辛苦画了半天,随便加个物体改个参数就要重画吧?
能想到的方法是,我们可以在引擎光照 uv 变更的时候对比旧数据,并从以前的数据里把手绘数据恢复回来。
(还得做个引擎内的笔刷工具,因为用不了 sp)
另一个方法就是用可绘制内容的投射器 (它的功能是和原始的光照结果 blend,而不是 add),它就像一个更高级的光源,可以增加光照笔刷的精度,如果只想对结果小修,这种做法就跟方便。最后发布时将结果烘焙到光照图上就好。
此外,如果普通光照的效果不仅仅是 “乘原色再线性减淡混合”“固定的衰减曲线”,而有更多的自由度的话(可选择不同混合模式),即使布光也更容易布出效果来。
但这又回到的之前分层调色的范畴。但调色和布光,本来也就是达到同一目的的两种手段。

体积光

pbr 出的新技术里,有大量增加真实感的特性,而它们都不太适合用到卡渲。
但有一个是例外,那就是体积光。
在 pbr 的环境下,其实很难找到容易触发丁达尔现象的场景,因为他们要顾及现实。如果你把这个效果做明显了,就显得整个场景都是雾蒙蒙的,但这个场景不该是雾蒙蒙的啊。
而卡渲里加上这东西,就不会给人这样的映像。
体积光在卡通渲染里出现的实在太频繁了,除了频繁出现的丁达尔光带之外,在灯光外面画一个 flare 模拟的也是这个,光特效严格来讲也是这个。
一些特意调高的 bloom,也是为了模拟光源外圈的体积光。
godray 这种 trick 体积光也是卡渲特别喜欢的。
体积光和体积雾其实本来就是一个东西,雾效在卡渲里也是很重要的元素。在白天缺乏体积光表现机会的情况下,就是雾的舞台。
如果将现在的符合物理的体积光 / 雾引入,代替之前的各种 trick 方法,是可以大幅提升画质的。
但标准体积光目前是一个非常昂贵的特性,移动平台基本不可能。但已经可以尝试一些局部的,低质的方法了,比如 raymarch 雾。只受单光源影响的 raymarch 投射光柱也是可以考虑的。
图形学发展这么久,卡渲却一直在使用各种古法,GI 搞了这么久却和它都没什么关系……
好不容易有一个能用的,自然要努力用上。 > 本文由简悦 SimpRead 转码