当前位置:   article > 正文

Unity Shader 实现卡通渲染效果_unityshader刷墙效果

unityshader刷墙效果

本文参考博客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
		}
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68

这就是一个比较简单的漫反射着色器
接下来把色阶降到两个
在这里插入图片描述
代码如下

	_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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

在这里我们引入_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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

最后我们需要增加一些高光和边缘光,效果如下(只是高光计算有点问题)
在这里插入图片描述
最后的代码

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
		}
	}
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114

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

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/107710
推荐阅读
相关标签
  

闽ICP备14008679号