Shader食谱 Chapter3--Toonshader卡通效果

unity shader toon 卡通Shader 

Shader食谱 Chapter3--Toonshader卡通效果

OverView

toon shader是游戏中比较常用的效果之一,尤其在二次元游戏中为了模拟角色在动画中手绘的效果。它是一种非真实的渲染技术,可以让3D角色显得平软很多。Toon效果实现过程主要是将大片光照接近的区域归到接近的步长,比如光照00.2全都为0,0.20.4全都视为0.2...这里主要通过两种方式来实现该效果。第一种使用坡度图映射光照,第二种使用算法来将光照分成不同步长

standardshader与toonshader比较:

方法一:使用坡度图RampMap

我们知道纹理的UV范围在0-1,我们如果将某一方向上颜色按一定的步长分隔,然后将初始的光照强度作为另一方向的 参数信息,由此则会获得按特定步长分隔的光照强度。

RampMap
Shader "ShaderCookbook/Toon" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex("Main Texture",2D)="white"{}
_RampTex("Ramp",2D)="white"{} }
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200 CGPROGRAM #pragma surface surf Toon
#pragma target 3.0 sampler2D _MainTex;
sampler2D _RampTex;
fixed4 _Color; struct Input {
float2 uv_MainTex;
}; fixed4 LightingToon(SurfaceOutput s,fixed2 lightDir,fixed atten){
half NdotL=dot(s.Normal,lightDir);
//uv范围0~1,这里通过fixed2(NdotL,0.5)从rampmap上取样,固定V的值为0.5,通过NdotL的值
//来在坡度图上取样,由此获得如cartoon中色彩分明的效果
//如果色彩在V轴上是固定的,那么V取0~1内的值结果都一致
NdotL=tex2D(_RampTex,fixed2(NdotL,0.5));
fixed4 c;
c.rgb=s.Albedo*_LightColor0*NdotL*atten;
c.a=s.Alpha;
return c;
} void surf (Input IN, inout SurfaceOutput o) {
fixed4 c=tex2D(_MainTex,IN.uv_MainTex)*_Color;
o.Albedo=c.rgb;
o.Alpha=c.a;
}
ENDCG
}
FallBack "Diffuse"
}

方法二:使用算法来分隔光照强度

本文中一开始的比较图中的Toonshader就是使用该方式CelShadingLevels为5时表现的效果,很明显看到角色上的光照显示出一层一层的样子,CelShadingLevels越高,这种分层效果就越细致。

//使用floor方法将按_CelshadingLevels等份得到的值向下取整,依然保[0-1]范围内的cel值

half cel = floor(NdotL * _CelShadingLevels) / (_CelShadingLevels -0.10);

下面是模拟取CelShadingLevels分别为3,5时候得到cel的值

GetCel
Shader "ShaderCookbook/Toon2" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
_MainTex("Main Texture",2D)="white"{}
_CelShadingLevels("_CelShading Levels",Range(0,10))=1 }
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200 CGPROGRAM #pragma surface surf CustomLambert
#pragma target 3.0 sampler2D _MainTex;
fixed4 _Color;
int _CelShadingLevels; struct Input {
float2 uv_MainTex;
}; half4 LightingCustomLambert (SurfaceOutput s, half3 lightDir, half3 viewDir, half atten) {
half NdotL = dot (s.Normal, lightDir); //使用floor方法将按_CelshadingLevels等份得到的值向下取整,依然保[0-1]范围内的cel值
half cel = floor(NdotL * _CelShadingLevels) / (_CelShadingLevels -0.10); //Snap
half4 c;
c.rgb = s.Albedo * _LightColor0.rgb * cel * atten;
c.a = s.Alpha;
return c;
} void surf (Input IN, inout SurfaceOutput o) {
fixed4 c=tex2D(_MainTex,IN.uv_MainTex)*_Color;
o.Albedo=c.rgb;
o.Alpha=c.a;
}
ENDCG
}
FallBack "Diffuse"
}

Shader食谱 Chapter3--Toonshader卡通效果的更多相关文章

  1. pixijs shader贴图扫光效果

    pixijs shader贴图扫光效果 直接贴代码 const app = new PIXI.Application({ transparent: true }); document.body.app ...

  2. Unity shader学习之屏幕后期处理效果之运动模糊

    运动模糊,代码如下: using UnityEngine; public class MotionBlurRenderer : PostEffectRenderer { [Range(0.1f, 0. ...

  3. Unity shader学习之屏幕后期处理效果之Bloom效果

    Bloom特效是游戏中常见的一种屏幕效果.这种特效可以模拟真实摄像机的一种图像效果,它让画面中较亮的区域“扩散”到周围的区域中,造成一种朦胧的效果. Bloom的实现原理很简单,首先根据一个阈值提取出 ...

  4. Unity shader学习之屏幕后期处理效果之高斯模糊

    高斯模糊,见 百度百科. 也使用卷积来实现,每个卷积元素的公式为: 其中б是标准方差,一般取值为1. x和y分别对应当前位置到卷积中心的整数距离. 由于需要对高斯核中的权重进行归一化,即使所有权重相加 ...

  5. Unity shader学习之屏幕后期处理效果之均值模糊

    均值模糊,也使用卷积来实现,之不过卷积中每个值均相等,且相加等于1. 代码如下, 子类: using UnityEngine; public class MeanBlurRenderer : Post ...

  6. Unity shader学习之屏幕后期处理效果之边缘检测

    边缘检测的原理是利用一些边缘检测算子对图像进行卷积操作. 转载请注明出处:http://www.cnblogs.com/jietian331/p/7232707.html 例如: 代码如下: usin ...

  7. Unity shader学习之屏幕后期效果之调整屏幕亮度,饱和度,对比度

    Unity的屏幕后期处理效果,使用MonoBehaviour.OnRenderImage来实现. 转载请注明出处:http://www.cnblogs.com/jietian331/p/7228063 ...

  8. three.js后期之自定义shader通道实现扫光效果

    如果你还不知道如何在three.js中添加后期渲染通道,请先看一下官方的一个最简单的demo : github. 正如demo中所示的那样,我们的扫光效果,也是一个自定义的ShaderPass. 所以 ...

  9. Unity shader学习之屏幕后期处理效果之高度雾,重建world pos方法2

    这里使用一种更高效地从深度纹理中重建世界坐标的方法. 首先计算摄像机的视锥体的四条射线向量进行线性插值,插值后的值便是该像素在世界空间坐标下到摄像机的方向. 然后通过与深度值相乘即可得到摄像机位置到该 ...

随机推荐

  1. html操作

    HTML(hyper text markup language): 超文本标记语言,标准通用标记语言下的一个应用. 超文本就是指页面内可以包含图片.连接.音乐.程序等非文字元素. 超文本标记语言的结构 ...

  2. 私有仓库harbor安装包括https

    1. 下载离线的 harbor gz包 wget https://github.com/vmware/harbor/releases/download/v1.2.0/harbor-offline-in ...

  3. c++ 堆和栈以及区别

    c++中内存分成5个区:堆.栈.自由存储区.全局\静态存储区.常量存储区 栈是一种连续存储的数据结构,具有先进后出的性质.堆是一种非连续的树形存储数据结构,每个节点有一个值,整棵树是经过排序的,特点是 ...

  4. 创建一个接口Shape,其中有抽象方法area,类Circle 、Rectangle实现area方法计算其面积并返回。又有Star实现Shape的area方法,其返回值是0,Star类另有一返回值boolean型方法isStar;在main方法里创建一个Vector,根据随机数的不同向其中加入Shape的不同子类对象(如是1,生成Circle对象;如是2,生成Rectangle对象;如是3,生成S

    题目补充: 创建一个接口Shape,其中有抽象方法area,类Circle .Rectangle实现area方法计算其面积并返回. 又有Star实现Shape的area方法,其返回值是0,Star类另 ...

  5. HDU 2602 Bone Collector(经典01背包问题)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2602 Bone Collector Time Limit: 2000/1000 MS (Java/O ...

  6. 在线调整InnoDB Buffer Pool Size

    InnoDB Buffer Pool主要是用来缓存数据表和索引数据的内存区域,它的默认值为134217728字节(128MB).最大值取决于CPU架构;32位系统上的最大值为4294967295(23 ...

  7. Kafka基础认识

    1):Apache kafka介绍及架构详解 假设一个场景: 数据源: 应用系统A 产生的用户访问数据和订单数据 10000 条一秒钟 push:推送数据 消息系统:队列 产生的数据量>数据量 ...

  8. kettle安装部署及远程执行

    一.windows环境 1.安装jdk 随意选择目录 只需把默认安装目录 \java 之前的目录修改即可 2.安装jre→更改→ \java 之前目录和安装 jdk 目录相同即可 注:若无安装目录要求 ...

  9. Linux 定时清除日志 Log

    一.原因 写这篇的原因是项目中log没有定时清除,服务器上项目是用脚本启动,log文件只会在启动时生成一次,这时,由于项目在不断运行中,导致log越来越大.如果删除log文件,还得把项目停掉在启动,这 ...

  10. 20155222 c语言实现pwd命令

    20155222 c语言实现linux的pwd命令 1.学习pwd命令在Linux层次结构中,用户可以在被授权的任意目录下利用mkdir命令创建新目录,也可以利用cd命令从一个目录转换到另一个目录.然 ...