上一篇传送门:

https://blog.csdn.net/qq_27534999/article/details/101080649

一、赛璐璐风格简介

有些人可能会问,什么是赛璐珞风格?

赛璐珞是一种合成树脂。最早在制作动画的时候,美国开始使用以赛璐珞制作的透明胶片,把人物画在胶片上面,背景画在纸上面,就可以做到很多不同的效果。

采用赛璐珞来制作的动画也叫“做赛璐珞动画”,在很长一个时期里面几乎是“手绘动画”的代名词。因为现在已经不用赛璐珞制作动画了,所以现在通常指有线稿和颜色的风格。以分层的方式作画(线稿层、明暗层、上色层、特效层)。

当然,具体风格依照动画不同,还是有所差异,这里仅挑选一个最经典的赛璐珞风格进行实现。

为了更直观的说明,这里以经典动画《星际牛仔》为例:

实际去看动画的话,可以发现人物有几个特征:

①黑色描边,较细且粗细均匀

②颜色平涂,并分为暗部亮部,暗部颜色根据环境不同会有所变化

③头发、金属、皮革等特殊部分会有高光、边缘光

④内部结构线、衬线

其中,第④点在本篇中暂时无法解决,一般的做法是直接画贴图上,不过会比较模糊,更好的办法以后再说吧嘻嘻 ~

首先,本篇会在前几篇的基础上改进 Shader 以实现效果,这里先上最终的效果图:

这边模型和背景比较简陋,可能效果不是很好,如果换更好的模型和背景的话效果会挺惊艳,个人感觉这种风格需要优秀美术资源配合才行,比如下图这样,也是用的相同 Shader:

有一点需要注意的是,这类赛璐珞风格渲染纹理不需要不要过多的细节,有时候多用单色色块反而效果会更好。

话不多说,那么接下来开始对之前的 Shader进行改造吧!

二、添加描边

为了方便观察分析,我们还是用之前那个简陋的模型(初学者专用),到上一篇为止的效果如下图所示:

在上一篇 Shader 的基础上,我们来添加描边,这里用一种比较经典的描边方法——顶点外扩(又称法线外扩、Shell 法)。

顶点外扩的原理就是新增一个 Pass,这个 Pass 将模型的顶点沿着法线向外移动一定距离,然后用 Cull Front 剔除正面,残留下来的面正好作为描边。另外,为了让描边在远近都能保持粗细均匀,我们还需要添加一些针对相机距离的计算。

性能优化注意:描边 Pass 务必放在 原 Pass 之后,这样就可以享受 Early-Z 带来的优化,防止造成 OverDraw!

该 Pass 代码具体如下:

Pass
{   Cull FrontCGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;};struct v2f{float2 uv : TEXCOORD0;UNITY_FOG_COORDS(1)float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;float _Outline;fixed4 _OutlineColor;v2f vert (appdata v){v2f o;//计算与相机的距离,用来保持描边粗细程度float3 posView = mul(UNITY_MATRIX_MV,v.vertex).xyz;float dis = length(posView);float3 normal = v.normal;//顶点沿法线挤出v.vertex = v.vertex + float4(normalize(normal), 0) * _Outline * dis * 0.01;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);UNITY_TRANSFER_FOG(o,o.vertex);return o;}fixed4 frag (v2f i) : SV_Target{// apply fogUNITY_APPLY_FOG(i.fogCoord, col);return _OutlineColor;}ENDCG
}

效果如下:

三、高光

参考《星际牛仔》的赛璐珞风格,我们不想在皮肤、衣物上有高光,这里可以调整顶点色(详见第三篇)或参数来控制细节,去除皮肤、衣物的高光,或者给金属材质加上高光,,这里就不再赘述。

第三篇顶点色细节控制传送门:https://blog.csdn.net/qq_27534999/article/details/100985558

去掉了大部分的边缘光,只保留鞋子部分的,调整后效果如下:

貌似没有原来好看,但为了还原赛璐珞的平涂风格,先这样吧。

四、阴影色

目前为止阴影色只是单纯的降低明度,然而有时候我们需要让阴影色根据环境来改变,这里有几个办法:

1、直接定义一个阴影色属性:

比较简单,就不多说了,将原来的 Shadow Brightness 阴影亮度换成阴影色即可。

2、根据 Lightning Settings 环境光参数进行调整:

#include "Lighting.cginc"
...
//使用Gradient
fixed3 abientSky = unity_AmbientSky.rgb;
fixed3 abientEquator = unity_AmbientEquator.rgb;
fixed3 abientGround = unity_AmbientGround.rgb;
//使用Color
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.rgb;

然后将 Shadow Brightness 阴影亮度换成相应变量即可。

调整后效果如下:

五、成果

另外,开头的另一张效果图,资源可在 Asset Store 免费下(TaichiCharacterPack)。

使用的是相同的Shader(没用顶点色控制),有兴趣的同学可以自己试试:

按惯例,放出完整 Shader 代码如下:

(直接用的话整个模型可能变得全白,这可能是因为模型没有刷顶点色,将 Shader 中 i.color 相关计算删除即可)

Shader "Custom/ToonShadingSimple_v4_SimpleCelluloid"
{Properties{[Header(Main)]_MainTex ("Texture", 2D) = "white" {}_Color ("Color", Color) = (1.0, 1.0, 1.0, 1.0)_ShadowColor ("ShadowColor", Color) = (1.0, 1.0, 1.0, 1.0)_RimColor ("RimColor", Color) = (1.0, 1.0, 1.0, 1.0)_ShadowThreshold ("ShadowThreshold", Range(-1.0, 1.0)) = 0.2//赛璐珞风格通常情况不使用边缘光,RimThreshold 可默认为1_RimThreshold ("RimThreshold", Range(0.0, 1.0)) = 1_RimPower ("RimPower", Range(0.0, 16)) = 4.0_Specular ("Specular", Color) = (1, 1, 1, 1)_SpecularScale("Specular Scale", Range(0, 0.1)) = 0.02_EdgeSmoothness("Edge Smoothness", Range(0,2)) = 2_Outline("Outline",Range(0,1))=0.1_OutlineColor("OutlineColor",Color)=(0,0,0,1)}SubShader{Tags { "RenderType"="Opaque" }LOD 100Pass{Cull BackTags { "LightMode"="ForwardBase" }CGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"#include "Lighting.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;fixed4 color : COLOR;};struct v2f{float2 uv : TEXCOORD0;float3 worldNormal : TEXCOORD1;float3 worldPos : TEXCOORD2;UNITY_FOG_COORDS(3)float4 vertex : SV_POSITION;fixed4 color : COLOR;};sampler2D _MainTex;float4 _MainTex_ST;fixed4 _Color;fixed4 _ShadowColor;fixed4 _RimColor;fixed _ShadowThreshold;fixed _RimThreshold;half _RimPower;half _EdgeSmoothness;fixed4 _Specular;fixed _SpecularScale;v2f vert (appdata v){v2f o;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;o.color = v.color;UNITY_TRANSFER_FOG(o,o.vertex);return o;}fixed4 frag (v2f i) : SV_Target{//return i.color;fixed3 worldNormal = normalize(i.worldNormal); //法线 Nfixed3 worldLightDir = normalize(UnityWorldSpaceLightDir(i.worldPos)); //光照方向 Lfixed3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos)); //视角方向 Vfixed3 worldHalfDir = normalize(worldLightDir + worldViewDir); //高光计算用// sample the texturefixed4 col = tex2D(_MainTex, i.uv); fixed spec = dot(worldNormal, worldHalfDir)+(i.color.g-0.5)*2;// w值也可用一个较小的值代替,效果差别不大fixed w = fwidth(spec)*_EdgeSmoothness;fixed4 specular = _Specular * lerp(0,1,smoothstep(-w, w, spec+_SpecularScale-1)) * step(0.001, _SpecularScale);fixed diffValue = dot(worldNormal, worldLightDir)+(i.color.r-0.5)*4;fixed diffStep = smoothstep(-w+_ShadowThreshold, w+_ShadowThreshold, diffValue);fixed4 light = _LightColor0 * 0.5 + 0.5;fixed4 diffuse = light * col * (diffStep + (1 - diffStep) * _ShadowColor) * _Color;// 模仿参考文章的方法,感觉效果不是太好// fixed rimValue = 1 - dot(worldNormal, worldViewDir);// fixed rimStep = step(_RimThreshold, rimValue * pow(dot(worldNormal,worldLightDir), _RimPower));fixed rimValue = pow(1 - dot(worldNormal, worldViewDir)+(i.color.b-0.5)*2, _RimPower);fixed rimStep = smoothstep(-w+_RimThreshold, w+_RimThreshold, rimValue);fixed4 rim = light * rimStep * 0.5 * diffStep * _RimColor;fixed4 final = diffuse + rim + specular;// apply fogUNITY_APPLY_FOG(i.fogCoord, final);return  final;}ENDCG}//注意,描边 Pass 放后边,可享受 Early-Z 优化Pass{  Cull FrontCGPROGRAM#pragma vertex vert#pragma fragment frag// make fog work#pragma multi_compile_fog#include "UnityCG.cginc"struct appdata{float4 vertex : POSITION;float2 uv : TEXCOORD0;float3 normal : NORMAL;};struct v2f{float2 uv : TEXCOORD0;UNITY_FOG_COORDS(1)float4 vertex : SV_POSITION;};sampler2D _MainTex;float4 _MainTex_ST;float _Outline;fixed4 _OutlineColor;v2f vert (appdata v){v2f o;//计算与相机的距离,用来保持描边粗细程度float3 posView = mul(UNITY_MATRIX_MV,v.vertex).xyz;float dis = length(posView);float3 normal = v.normal;//顶点沿法线挤出v.vertex = v.vertex + float4(normalize(normal), 0) * _Outline * dis * 0.01;o.vertex = UnityObjectToClipPos(v.vertex);o.uv = TRANSFORM_TEX(v.uv, _MainTex);UNITY_TRANSFER_FOG(o,o.vertex);return o;}fixed4 frag (v2f i) : SV_Target{// apply fogUNITY_APPLY_FOG(i.fogCoord, col);return _OutlineColor;}ENDCG}}
}

下一篇传送门:

下一篇还没想好要写啥,先这么放着吧

参考文章:

1、萌娘百科 - 赛璐珞

https://zh.moegirl.org/%E8%B5%9B%E7%92%90%E7%8F%9E

2、【NPR】漫谈轮廓线的渲染

https://blog.csdn.net/candycat1992/article/details/45577749

Unity Shader 卡通渲染 (五):仿日式赛璐珞风格 Shader(顶点外扩描边)相关推荐

  1. Unity Shader 卡通渲染 实时模型动画描边的研究

    前言 卡通渲染也叫非真实感渲染(英文简写:NPR),"描边"在图形学和数字图像里都叫边缘检测.因此你可以在很多文献网站上面找到很多这类文献,但最后我发现基于图形学使用的方式基本都是 ...

  2. Unity Shader 卡通渲染 模型描边之退化四边形

    目录 前言 一.基于空间的边缘检测算法 二.退化四边形 三.Unity中的CommandBuffer和ComputeBuffer 四.构成描边的简单实例 五.模型描边的实现 前言 之前写了一篇< ...

  3. Unity Shader卡通渲染 · 高清渲染管线·HDRP

    Unity Shader卡通渲染 · 高清渲染管线·HDRP 前言 最近在研究HDRP管线中的卡通渲染,就想着能不能把官方的UCTS移植到HDRP管线里面去,说干就干,到昨天晚上上传了github,今 ...

  4. 新房装修的简约日式装修风格技巧和装修攻略

    日式装修风格是现在极为流行的一种装修风格,因为它注重自然与简约,大量使用浅色和原木色,非常符合现在90后的一种审美标准,即减法就等于加法.日式装修风格也分为很多种,今天佛山装修公司的小编分享的是简约日 ...

  5. 3.顶点外扩方法实现的描边shader

    描边shader的实现有很多种,顶点外扩是其中之一.顶点外扩的原理是用2个Pass 渲染物体2次 第一遍:描边,顶点沿法线方向外拓后用黑色渲染.外扩这一步的实现是在投影空间,也就是2D的,根绝法线的x ...

  6. Unity Shader 卡通渲染 (三):仿塞尔达荒野之息 Shader(顶点色控制细节)

    上一篇传送门: https://blog.csdn.net/qq_27534999/article/details/100925621 顶点色在卡通渲染中有挺多应用,本篇会在上一篇的基础上,运用模型顶 ...

  7. Unity Shader 卡通渲染 (一):仿塞尔达荒野之息 Shader(简易版)

    温馨提示: 本系列文章面向那些 Shader 刚刚入门,想寻求进一步提升的群体,如果对 Shader 一无所知的话,建议自行搜索其他 Shader入门教程观看学习,再食用本系列文章. 前言: 说起卡通 ...

  8. unity shader卡通渲染(描边)+阴影+多光源处理

    说道卡通渲染,应该都会想到描边: 我所学的描边有三种: 一种是计算边缘深度检测描边 一种是色差检测描边 一种是利用顶点法线向外扩展返回单色pass,使用正面裁剪 我用的第三种: pass {//剔除前 ...

  9. [Unity Shader]卡通渲染

    最终效果,包含描边,明暗双色阶的渲染,边缘光. 参考来源:https://www.zhihu.com/column/c_1215952152252121088 卡通渲染 Back facing描边 光 ...

最新文章

  1. 数据结构-单链表(C语言代码)
  2. 全球及中国皮革和纺织品用甲酸行业竞争调查分析及投资规划报告2021年版
  3. 计算机网络是如何通信的【二】
  4. 一个命令kill所有符合条件的进程
  5. [BUUCTF-pwn]——[ZJCTF 2019]Login
  6. 弟子规python编程游戏_《Python游戏趣味编程》 第11章 消灭星星
  7. Linux关机运行的脚本,Linux 关机 脚本
  8. Vuex原来可以这样上手
  9. UI设计灵感|有声读物APP界面设计
  10. java中properties类_Java中的Properties类详解
  11. 惠普暗影精灵3清灰_惠普暗影精灵15评测:速度超快,价格适中|但问题却不少...
  12. 把握这两点,抢占下一个电商风口|2016最新中国电商App排名研究报告
  13. 基于知识图谱的智能问答机器人技术架构
  14. python tkinter label标签_Python Tkinter详解 (二)Label标签的使用
  15. 李嘉诚:成功创业要具备的五个要素
  16. 最小生成树之Prim(普里姆)算法
  17. 《敏捷整洁之道 回归本源》阅读表述
  18. 深度细节 | Go 的 panic 的秘密都在这
  19. 批量上传图片_微信公众号关键词回复图片突破200条规则,怎么设置?
  20. winxp系统连接服务器丢包解决方法

热门文章

  1. 2022茶艺师(中级)试题及答案
  2. CentOS 固定 IP 地址
  3. 用于土地使用和土地覆盖分类的landsat8的OLI波段组合的选择
  4. spooling 技术工作原理
  5. 使用python爬取电影下载地址并使用transmissionrpc下载
  6. 【Python】爬取金庸射雕英雄传连载版以及金庸作品里所有江湖门派
  7. 世界是如何由计算机代码运行的(原文见http://www.bbc.co.uk/timelines/zxsrcdm)
  8. 部署并安装Discuz论坛(首先搭建LAMP环境Apache+MySQL+PHP)
  9. Matlab论文插图绘制模板第31期—堆叠折线图(stackedplot)
  10. 百度音乐2013 8.2.8 去广告VIP绿色版|zd423作品