基于unity2018的NPR Toon Shading的一般实现
Thepoly 15436 2
实名

通过了实名认证的内容创造者

发布于 2022-3-26 14:54:22

您需要 登录 才可以下载或查看,没有账号?注册

x
本帖最后由 Thepoly 于 2022-3-26 14:57 编辑

             src=http___img-blog.csdnimg.cn_img_convert_bb16c68e8b798b1ea8771e1b08482ac3.pngrefer=http___img-blog.csdnimg.webp.jpg
174551k9r66ex7z719e99h.jpg


Hello . 大家好
今天是来自王掌柜的文章分享


上一期在介绍fur shader之后,一些朋友问如何实现卡通渲染效果。之后打算利用unity简单的介绍一下实现方法,当然这里这是把最核心的视觉效果写出,在明白基本原理后,可以自主的写一些小效果加进去来增强画面表现。

二次元渲染效果,实际上说的是Toon shading。Toon shading在一些Celluloid(赛璐珞)风格游戏中经常被用到,比如游戏行尸走肉、国产游戏崩坏3、凯瑟琳、女神异闻录(日本游戏居多)等等,这种渲染方式接近二次元卡通效果同时十分的Cheap,手机神马的扛得住,而且简化了模型制作流程,游戏趋向轻量级,所以逐渐被应用推广。

Toon shading实际上是一种Non-photorealistic Rendering(非真实性渲染)技术。下面两图,右边的是 Standard Shader下的效果,左边则是toon Shader 的效果。


获得Celluloid效果,用surface function也是可以的,但是开销会很大,surface function只作用于材质的属性,而不是实际光照。 Toon shading要求在应用时可改变光线的反射,所以我们需要创建一个光照模型来达到渲染目的。

一般来说,实现Toon shading需要一张特殊的贴图:Ramp map(如下图所示)。




当正常填充材质颜色时,这张图用于指定着色层次。这里面需要注意,当你导入一张自制的ramp map时,需要在Inspector面板中将ramp map的Wrap Mode调整为Clamp,如果你想让颜色间的交界边缘更加锐利,Filter Mode也要相应调整为Point。

之后还是老套路,创建一个球、一个材质、一个shader,用VS打开shader进行编程。之后来简单介绍一下基本实现原理:
1.添加RampTex贴图
  1. _RampTex ("Ramp", 2D) = "white" {}
点击此处复制文本


2.添加其关联变量
  1. sampler2D _RampTex;
点击此处复制文本


3.改变一下#pragma指令
  1. #pragma surface surf Toon
点击此处复制文本


4.将LightingSimpleLambert函数替换掉,加入下列代码
  1. fixed4 LightingToon (SurfaceOutput s, fixed3 lightDir, fixed atten)
  2. {  
点击此处复制文本

//首先计算光线与表面法线的点积
  1. half NdotL = dot(s.Normal, lightDir);  
点击此处复制文本

//NdotL在ramp图上重映射NdotL
  1. NdotL = tex2D(_RampTex, fixed2(NdotL, 0.5));
点击此处复制文本

//之后确定被返回的颜色
  1. half4 color;

  2. color.rgb = s.Albedo * _LightColor0.rgb * (NdotL * atten );  
  3. color.a = s.Alpha;
点击此处复制文本


//返回计算后的颜色
  1. return color;
  2. }
点击此处复制文本


5.保存shader脚本,打开材质球,开始对相应属性进行调试,如下:

6.Toon shading效果会根据环境光照发生改变,这里为了观测方便,在Window | Lighting | Settings目录下将 Environment | Environment Lighting | Intensity Multiplier属性值调整为0.

7.实现原理
Toon shading实现的这种特殊光线效果仅靠Surface很难完美实现,所以我们需要一张 Ramp map,旨在将Lambertian光照强度NdotL重映射为其他数值。利用非渐变的Ramp map,可以将光照强制渲染为具有梯度特点的效果。原理如下图所示:

8.其实可以用很多方法来实现 Toon shading效果。利用不同的ramp可以在你的模型上产生剧烈的梯度变化。还有一种可以替代ramp map的方法是去强制Snap光线强度NdotL,这样梯度变化可以在0到1之间进行采样来控制,代码如下:

  1. half4 LightingCustomLambert (SurfaceOutput s, half3 lightDir,  half3 viewDir, half atten)
  2. {  
  3. half NdotL = dot (s.Normal, lightDir);
  4. half cel = floor(NdotL * _CelShadingLevels) /(_CelShadingLevels - 0.5);
  5. half4 color;
  6. color.rgb = s.Albedo * _LightColor0.rgb * (cel * atten );
  7. color.a = s.Alpha;
  8. return color;
  9. }
点击此处复制文本


实现效果如下:

虚幻或是其他引擎的实现思路基本一致,各位看官可尝试再开一些属性栏或是绘制不同的Ramp进行制作。今天的分享就到这里,掌柜告辞


- End -

喜欢Thepoly的可以通过三种方式与我们建立联系。分别是公众号、微信群以及QQ群。公众号是我们最为官方的窗口,更多内容都必须关注公众号后才能获取。另外现以开通微博:手机版http://weibo.cn/thepoly网页版http://weibo.com/thepoly

本帖被以下画板推荐:

还没有设置签名!您可以在此展示你的链接,或者个人主页!
使用道具 <
Teny  发表于 2022-3-26 18:43:14  
3#
谢谢楼主分享!!!
回复 收起回复
使用道具
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表