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. 谈谈 C++ 中的右值引用

    转自:https://liam0205.me/2016/12/11/rvalue-reference-in-Cpp/ 最近在改 XGBoost 的代码.XGBoost 在代码中使用了很多来自 C++1 ...

  2. SpringMVC如何防御CSRF

    本文说一下SpringMVC如何防御CSRF(Cross-site request forgery跨站请求伪造)和XSS(Cross site script跨站脚本攻击). 说说CSRF 对CSRF来 ...

  3. React & TypeScript

    之前看了一下 TypeScript 的知识,但是一直没有上手,最近开始结合 React 和 TypeScript 一起尝试了一下,感受还是很好的,所以写一下笔记. 环境配置没有参考其他东西,就是看了下 ...

  4. impala jdbc驱动执行impala sql的一个坑(不支持多行sql)

    架构使用spark streaming 消费kafka的数据,并通过impala来插入到kudu中,但是通过对比发现落地到kudu表中的数据比kafka消息数要少,通过后台日志发现,偶发性的出现jav ...

  5. c++—— 函数重载(Overroad)

    5 函数重载(Overroad) 函数重载概念 1 函数重载概念 函数重载(Function Overload) 用同一个函数名定义不同的函数 当函数名和不同的参数搭配时函数的含义不同 2 函数重载的 ...

  6. JS判断指定dom元素是否在屏幕内的方法实例

    前言 刷网页的时候,有时会遇到这样一个情景,当某个dom元素滚到可见区域时,或者图片的懒加载效果,它就会展现显示动画,十分有趣.那么这是如何实现的呢? 实现原理 想要实现这个功能,就要知道具体的实现原 ...

  7. CommonJS、AMD、CMD、NodeJs、RequireJS到底有什么联系?

    JS中的模块规范(CommonJS,AMD,CMD),如果你听过js模块化这个东西,那么你就应该听过或CommonJS或AMD甚至是CMD这些规范,本文包括这三个规范的来源及对应的产物的原理. 一.C ...

  8. 解决yum安装 openssl-devel时产生的Multilib version problems found错误(转)

    Error: Multilib version problems found. This often means that the root cause is something else and m ...

  9. C++内存管理变革(6):通用型垃圾回收器 - ScopeAlloc

    本文已经迁移到:http://cpp.winxgui.com/cn:a-general-gc-allocator-scopealloc C++内存管理变革(6):通用型垃圾回收器 - ScopeAll ...

  10. linux iSCSI target/initiator配置

    linux iSCSI target配置全过程一:Install iSCSI target for Linux1,操作系统:[root@rac2 ~]# cat /etc/issueEnterpris ...