UE Toon渲染半影着色实现指南:纯色法与Ramp法详解
- 作者:admin
- /
- 时间:一小时前
- /
- 浏览:10 次
- /
- 分类:厚积薄发
【USparkle专栏】如果你深怀绝技,爱“搞点研究”,乐于分享也博采众长,我们期待你的加入,让智慧的火花碰撞交织,让知识的传递生生不息!
一、前言
在动画或者卡通渲染存在一个很常见的效果,光源的边界染上一个饱和度较高的颜色,这个效果业内一般称作半影着色:

《吹响吧!上低音号》

《别当欧尼酱了》

《绝区零》
在HDRP中也有类似的效果:

Unity里的实现非常简单,就是拿一个纯色来给半影染色:

除了Unity的这种实现方式,还有一种常见的实现方法是用阴影来采样Ramp:

https://zhuanlan.zhihu.com/p/588991753

https://zhuanlan.zhihu.com/p/688482736
二、实现思路
2.1 纯色法
首先在光源组件上添加新的参数:


LightComponent.h
接下来正常把这些参数传给Shader就行,半影颜色的计算直接抄HDRP:

ToonLightCommon.ush
在光照计算的时候调用ComputeShadowColor:

DeferredLightingCommon.ush
接下来就能看到效果了:
半影着色_1
效果还挺不错的,多光影也可以完美兼容:

不过,有一个尴尬的问题,从上面的视频效果图可以发现,主光的半影着色并没有作用在Toon角色上,这也正常,毕竟Toon角色的主光是在ToonLightPass里单独计算的。
按照正常的逻辑,我们应该把染过色的Shadow传给ToonLightPass,但是,这样需要再用3个通道来存储阴影,之前的ToonShadow已经满了,这样得新创建一张,有些浪费了。
所以我干脆还是把半影的参数传到ToonLightPass,然后在ToonLightPass自己去计算。

这样做还有个好处,如果觉得半影颜色在角色上有点太强了,很容易可以调节强度:
半影着色_2
2.2 Ramp法
同样的,在光源上添加新的参数:

传参方式和以往有所区别,如果把Ramp贴图放到FLightShaderParameters里的话会报错:

SceneManagement.h
所以我把贴图放到FDeferredLightUniformStruct里,FToonLightUniformParameters也一样:

LightRendering.h

ToonLightPassRendering.h
采样贴图的时候由于不同Pass里Buffer的名字不一样,所以在Shader上添加宏来区分:

LightRendering.cpp

ToonLightPassRendering.h

ToonLightCommon.ush
在材质编辑器里也使用相同的函数来计算半影:

看看效果:
三、参考和链接
3.1 链接
本文的修改都上传GitHub了,对应下图的提交记录:

https://github.com/Yu-ki016/UnrealEngine/tree/YK_Engine
示例工程:
https://github.com/Yu-ki016/YKEngineExampleProject
3.2 参考
[1] Unity URP 8Cascade+PCF/PCSS 阴影+Compute Shader屏幕空间shadowmap+阴影渐变
[2] 图形引擎实战:8级风格化级联阴影
这是侑虎科技第1990篇文章,感谢作者Yu-ki016供稿。欢迎转发分享,未经作者授权请勿转载。如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)
作者主页:https://www.zhihu.com/people/yu-ki-016
再次感谢Yu-ki016的分享,如果您有任何独到的见解或者发现也欢迎联系我们,一起探讨。(QQ群:793972859)

