赞
踩
本文参考博客Unity Toon Shader 卡通着色器(一):卡通着色
这是我实现的最后效果
我们先一步一步来
最开始我们实现一个只有漫反射效果的Shader,效果和代码如下
Shader "Unlit/ToonLearn" { Properties { _MainTex ("Texture", 2D) = "white" {} _Color("Color",Color)=(1,1,1,1) } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Tags {"LightMode"="ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 normal:NORMAL; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float3 normal:TEXCOORD1; }; sampler2D _MainTex; float4 _MainTex_ST; float3 _Color; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.normal=mul(v.normal,(float3x3)unity_WorldToObject); return o; } fixed4 frag (v2f i) : SV_Target { fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz); float3 normal=normalize(i.normal); float NdotL=saturate(dot(normal,lightDir)); fixed3 albedo = tex2D(_MainTex, i.uv)*_Color.rgb; fixed3 diffuse= albedo*_LightColor0.rgb*NdotL; float4 finalColor=float4(diffuse,1); return finalColor; } ENDCG } } }
这就是一个比较简单的漫反射着色器
接下来把色阶降到两个
代码如下
_RampThreshold("Ramp Threshold",Range(0,1))=0.5
_RampSmooth("Smooth Threshold",Range(0,1))=0.1
......
fixed3 ramp=smoothstep(_RampThreshold-_RampSmooth*0.5,
_RampThreshold+_RampSmooth*0.5,NdotL);
fixed3 albedo = tex2D(_MainTex, i.uv)*_Color.rgb;
fixed3 diffuse= albedo*_LightColor0.rgb*ramp;
在这里我们引入_RampThreshold,当NdotL>_RampThreshold,ramp=1,当NdotL<_RampThreshold,ramp=0,
同时我们引入_RampSmooth作为平滑度,同时使smoothstep进行平滑过渡,这篇博客对smoothstep的介绍就挺好的Shader smoothstep使用
接下来我们可以用颜色叠加来作为阴影和亮部,于是引入了_SColor和_HColor,挑一个好看的参数。
反正比黑漆漆要好看得多,以下是代码
_HColor ("Highlight Color", Color) = (0.8, 0.8, 0.8, 1.0)
_SColor ("Shadow Color", Color) = (0.2, 0.2, 0.2, 1.0)
...
_SColor=lerp(_HColor,_SColor,_SColor.a);
float3 rampColor=lerp(_SColor.rgb,_HColor.rgb,ramp);
fixed3 diffuse= albedo*_LightColor0.rgb*rampColor;
最后我们需要增加一些高光和边缘光,效果如下(只是高光计算有点问题)
最后的代码
Shader "Unlit/ToonLearn" { Properties { _MainTex ("Texture", 2D) = "white" {} _RampThreshold("Ramp Threshold",Range(0,1))=0.5 _RampSmooth("Smooth Threshold",Range(0,1))=0.1 _Color("Color",Color)=(1,1,1,1) _HColor ("Highlight Color", Color) = (0.8, 0.8, 0.8, 1.0) _SColor ("Shadow Color", Color) = (0.2, 0.2, 0.2, 1.0) _SpecularColor ("Specular Color", Color) = (0.5, 0.5, 0.5, 1) _SpecThreshold ("Specular Threshold", Range(0, 1)) = 0.5 _SpecSmooth ("Specular Smooth", Range(0, 1)) = 0.1 _Shininess ("Shininess", Range(0.001, 10)) = 0.2 _RimColor ("Rim Color", Color) = (0.8, 0.8, 0.8, 0.6) _RimThreshold ("Rim Threshold", Range(0, 1)) = 0.5 _RimSmooth ("Rim Smooth", Range(0, 1)) = 0.1 } SubShader { Tags { "RenderType"="Opaque" } LOD 100 Pass { Tags {"LightMode"="ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 normal:NORMAL; }; struct v2f { float2 uv : TEXCOORD0; float4 vertex : SV_POSITION; float3 normal:TEXCOORD1; }; sampler2D _MainTex; float4 _MainTex_ST; float4 _Color; float4 _SColor; float4 _HColor; float _RampThreshold; float _RampSmooth; float4 _SpecularColor; float _SpecThreshold; float _SpecSmooth; float _Shininess; float4 _RimColor; float _RimThreshold; float _RimSmooth; v2f vert (appdata v) { v2f o; o.vertex = UnityObjectToClipPos(v.vertex); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.normal=mul(v.normal,(float3x3)unity_WorldToObject); return o; } fixed4 frag (v2f i) : SV_Target { fixed3 lightDir=normalize(_WorldSpaceLightPos0.xyz); fixed3 viewDir=normalize(_WorldSpaceCameraPos.xyz); fixed3 halfDir=normalize(lightDir+viewDir); float3 normal=normalize(i.normal); float NdotL=saturate(dot(normal,lightDir)); float NdotH=saturate(dot(normal,halfDir)); float NdotV=saturate(dot(normal,viewDir)); fixed3 ramp=smoothstep(_RampThreshold-_RampSmooth*0.5, _RampThreshold+_RampSmooth*0.5,NdotL); fixed4 albedo = tex2D(_MainTex, i.uv)*_Color; _SColor=lerp(_HColor,_SColor,_SColor.a); float3 rampColor=lerp(_SColor.rgb,_HColor.rgb,ramp); fixed3 diffuse= albedo.rgb*_LightColor0.rgb*rampColor; float gloss=albedo.a; float spec=pow(NdotH,_Shininess*128)*gloss; spec=smoothstep(_SpecThreshold-_SpecSmooth*0.5, _SpecThreshold+_SpecSmooth*0.5,spec); fixed3 specular=_SpecularColor.rgb*_LightColor0.rgb*spec; float rim=(1-NdotV)*NdotL; rim=smoothstep(_RimThreshold-_RimSmooth*0.5,_RimThreshold+_RimSmooth*0.5,rim); fixed3 rimColor=_RimColor.rgb*_LightColor0.rgb*_RimColor.a*rim; float4 finalColor=float4(diffuse+specular+rimColor,1); return finalColor; } ENDCG } } }
这就是全部了,感谢你的阅读,如有错误,欢迎指正。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。