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


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

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的值

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卡通效果的更多相关文章
- pixijs shader贴图扫光效果
pixijs shader贴图扫光效果 直接贴代码 const app = new PIXI.Application({ transparent: true }); document.body.app ...
- Unity shader学习之屏幕后期处理效果之运动模糊
运动模糊,代码如下: using UnityEngine; public class MotionBlurRenderer : PostEffectRenderer { [Range(0.1f, 0. ...
- Unity shader学习之屏幕后期处理效果之Bloom效果
Bloom特效是游戏中常见的一种屏幕效果.这种特效可以模拟真实摄像机的一种图像效果,它让画面中较亮的区域“扩散”到周围的区域中,造成一种朦胧的效果. Bloom的实现原理很简单,首先根据一个阈值提取出 ...
- Unity shader学习之屏幕后期处理效果之高斯模糊
高斯模糊,见 百度百科. 也使用卷积来实现,每个卷积元素的公式为: 其中б是标准方差,一般取值为1. x和y分别对应当前位置到卷积中心的整数距离. 由于需要对高斯核中的权重进行归一化,即使所有权重相加 ...
- Unity shader学习之屏幕后期处理效果之均值模糊
均值模糊,也使用卷积来实现,之不过卷积中每个值均相等,且相加等于1. 代码如下, 子类: using UnityEngine; public class MeanBlurRenderer : Post ...
- Unity shader学习之屏幕后期处理效果之边缘检测
边缘检测的原理是利用一些边缘检测算子对图像进行卷积操作. 转载请注明出处:http://www.cnblogs.com/jietian331/p/7232707.html 例如: 代码如下: usin ...
- Unity shader学习之屏幕后期效果之调整屏幕亮度,饱和度,对比度
Unity的屏幕后期处理效果,使用MonoBehaviour.OnRenderImage来实现. 转载请注明出处:http://www.cnblogs.com/jietian331/p/7228063 ...
- three.js后期之自定义shader通道实现扫光效果
如果你还不知道如何在three.js中添加后期渲染通道,请先看一下官方的一个最简单的demo : github. 正如demo中所示的那样,我们的扫光效果,也是一个自定义的ShaderPass. 所以 ...
- Unity shader学习之屏幕后期处理效果之高度雾,重建world pos方法2
这里使用一种更高效地从深度纹理中重建世界坐标的方法. 首先计算摄像机的视锥体的四条射线向量进行线性插值,插值后的值便是该像素在世界空间坐标下到摄像机的方向. 然后通过与深度值相乘即可得到摄像机位置到该 ...
随机推荐
- html操作
HTML(hyper text markup language): 超文本标记语言,标准通用标记语言下的一个应用. 超文本就是指页面内可以包含图片.连接.音乐.程序等非文字元素. 超文本标记语言的结构 ...
- 私有仓库harbor安装包括https
1. 下载离线的 harbor gz包 wget https://github.com/vmware/harbor/releases/download/v1.2.0/harbor-offline-in ...
- c++ 堆和栈以及区别
c++中内存分成5个区:堆.栈.自由存储区.全局\静态存储区.常量存储区 栈是一种连续存储的数据结构,具有先进后出的性质.堆是一种非连续的树形存储数据结构,每个节点有一个值,整棵树是经过排序的,特点是 ...
- 创建一个接口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类另 ...
- HDU 2602 Bone Collector(经典01背包问题)
题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2602 Bone Collector Time Limit: 2000/1000 MS (Java/O ...
- 在线调整InnoDB Buffer Pool Size
InnoDB Buffer Pool主要是用来缓存数据表和索引数据的内存区域,它的默认值为134217728字节(128MB).最大值取决于CPU架构;32位系统上的最大值为4294967295(23 ...
- Kafka基础认识
1):Apache kafka介绍及架构详解 假设一个场景: 数据源: 应用系统A 产生的用户访问数据和订单数据 10000 条一秒钟 push:推送数据 消息系统:队列 产生的数据量>数据量 ...
- kettle安装部署及远程执行
一.windows环境 1.安装jdk 随意选择目录 只需把默认安装目录 \java 之前的目录修改即可 2.安装jre→更改→ \java 之前目录和安装 jdk 目录相同即可 注:若无安装目录要求 ...
- Linux 定时清除日志 Log
一.原因 写这篇的原因是项目中log没有定时清除,服务器上项目是用脚本启动,log文件只会在启动时生成一次,这时,由于项目在不断运行中,导致log越来越大.如果删除log文件,还得把项目停掉在启动,这 ...
- 20155222 c语言实现pwd命令
20155222 c语言实现linux的pwd命令 1.学习pwd命令在Linux层次结构中,用户可以在被授权的任意目录下利用mkdir命令创建新目录,也可以利用cd命令从一个目录转换到另一个目录.然 ...