900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > Unity Shader 实现卡通渲染效果

Unity Shader 实现卡通渲染效果

时间:2021-06-03 09:22:29

相关推荐

Unity Shader 实现卡通渲染效果

本文参考博客Unity Toon Shader 卡通着色器(一):卡通着色

这是我实现的最后效果

我们先一步一步来

最开始我们实现一个只有漫反射效果的Shader,效果和代码如下

Shader "Unlit/ToonLearn"{Properties{_MainTex ("Texture", 2D) = "white" {}_Color("Color",Color)=(1,1,1,1)}SubShader{Tags {"RenderType"="Opaque" }LOD 100Pass{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 100Pass{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}}}

这就是全部了,感谢你的阅读,如有错误,欢迎指正。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。