shader卡通渲染

(1)效果 : 果然开启bloom 录屏就是会有问题

请添加图片描述
在这里插入图片描述
没啥好说的,直接上代码:

Shader "Unlit/MaLi"
{
    
    
	Properties
	{
    
    
		_BaseMap ("_BaseMap", 2D) = "white" {
    
    }
		_SSSMap ("_SSSMap", 2D) = "white" {
    
    }
		_ILM ("_ILM", 2D) = "white" {
    
    }
		_DetailMap ("_DetailMap", 2D) = "white" {
    
    }
		_ToonTheshold("_ToonTheshold",range(0,1)) = 0.5
		_ToonHardness("_ToonHardness",float) = 50

		_SpecSzie("_SpecSzie",range(0,1)) = 0.1



		// 第二个pass
		_OutLineWidth("_OutLine",range(0,0.01)) = 1
		_OutLineColor("_OutLineColor",color) = (0,0,0,0)
		_OutlineZbias("_OutlineZbias",range(0,1)) = 1

		// 补光   边缘光
		_RimLightDir("_RimLightDir",vector) = (0,0,0,0)
		_RimLightColor("_RimLightColor",color) = (0,0,0,0)
	}
	SubShader
	{
    
    
		Tags {
    
     "RenderType"="Opaque" "LightMode"="ForwardBase"}
		LOD 100

		Pass
		{
    
    
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_fwbase 
			
			#include "UnityCG.cginc"

			struct appdata
			{
    
    
				float4 vertex : POSITION;
				float2 texcoord0 : TEXCOORD0;
				float2 texcoord1 : TEXCOORD1;
				float3 normal : NORMAL;
				float4 color : COLOR;
				
			};

			struct v2f
			{
    
    
				float4 uv : TEXCOORD0;
				float3 pos_World : TEXCOORD1;
				float3 normal_World : TEXCOORD2;
				float4 pos : SV_POSITION;
				float4 vertex_color : TEXCOORD3;
			};

			sampler2D _BaseMap,_SSSMap,_ILM,_DetailMap;
			float4 _BaseMap_ST,_SSSMap_ST,_ILM_ST,_DetailMap_ST;
			
			float _ToonTheshold,_ToonHardness,_SpecSzie;


			float4 _RimLightColor;
			float3 _RimLightDir;
			v2f vert (appdata v)
			{
    
    
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.pos_World = mul(unity_ObjectToWorld,v.vertex).xyz;
				o.normal_World = UnityObjectToWorldNormal(v.normal);
				o.uv = float4(v.texcoord0,v.texcoord1);
				o.vertex_color = v.color;
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
    
    

				half2 uv1 = i.uv.xy;
				half2 uv2 = i.uv.zw;
			
				float3 normalDir = normalize(i.normal_World);
				float3 lightDir = normalize(UnityWorldSpaceLightDir(i.pos_World));

				// base 主贴图
				float4 base_map = tex2D(_BaseMap,uv1);
				// 亮部颜色
				float3 base_color = base_map.rgb;
				// 用来区分皮肤头发 和非皮肤区域
				float base_mask = base_map.a;

				// 暗部计算
				float4 sss_map = tex2D(_SSSMap,uv1);
				// 暗部的颜色
				float3 sss_color = sss_map.rgb;
				// 边缘光的强度控制
				float sss_alpha = sss_map.a;

				// ILM 贴图
				float4 ilm_map = tex2D(_ILM,uv1);
				// 控制高光强度
				float spec_intensity = ilm_map.r;
				// 控制光照的偏移
				float diffuse_control = ilm_map.g * 2.0 - 1.0;
				// 控制高光形状的大小
				float spec_size = ilm_map.b;
				// 内描线
				float inner_line = ilm_map.a;

				// 顶点色
				float ao = i.vertex_color.r;



				// diffuse
				float NdotL= dot(normalDir,lightDir);
				float half_lambert = (NdotL + 1.0) * 0.5;
				float larmbert_term = half_lambert * ao + diffuse_control;
				float toon_diffuse = saturate(larmbert_term - _ToonTheshold) * _ToonHardness;
				float3 final_diffuse = lerp(sss_color,base_color,toon_diffuse);


				// 高光
				float3 viewDir =  normalize(UnityWorldSpaceViewDir(i.pos_World));
				float ndotV = dot(normalDir,viewDir);
				float spec_term = (ndotV+1.0) * 0.5;
				spec_term = spec_term * ao + diffuse_control;
				spec_term = half_lambert * 0.9 + spec_term * 0.1;
				float toon_spec = saturate((spec_term - (1.0 - spec_size - _SpecSzie)) * 500 );
				float3 final_spec = toon_spec * base_color * spec_intensity;
				//return float4(toon_spec.xxx,1.0);

				// 内描线
				float3 inner_line_color = lerp(base_color * 0.2, float3(1.0,1.0,1.0),inner_line);
				// 第二套uv  Detail 细节贴图
				float3 detail_color = tex2D(_DetailMap,uv2);
				detail_color = lerp(base_color * 0.2, float3(1.0,1.0,1.0),detail_color);
				float3 final_line = inner_line_color * inner_line_color * detail_color;



				// 补光  边缘
				float3 lightDir_rim = normalize(mul((float3x3)unity_MatrixInvV,_RimLightDir.xyz));
				float NdotL_rim = (dot(normalDir,lightDir_rim) + 1.0) * 0.5;
				float rimLight_term = NdotL_rim + diffuse_control;
				float toon_rim = saturate((rimLight_term - _ToonTheshold) * 20);
				float3 rim_color = (_RimLightColor.rgb + base_color.rgb) * 0.5 * sss_alpha;
				// 最后乘以  toon_diffuse  跑到diffuse 阴影区域就会隐藏
				float3 final_rimLight = toon_rim * rim_color * base_mask * toon_diffuse * _RimLightColor.a;





				float3 final_color = (final_spec + final_diffuse) * final_line;
				final_color = sqrt(max(exp2(log2(max(final_color,0.0))* 2.2),0.0));

				return float4(final_color,1.0);
			}
			ENDCG
		}

		Pass
		{
    
    
			cull Front
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag			
			#include "UnityCG.cginc"

			struct appdata
			{
    
    
				float4 vertex : POSITION;
				float2 texcoord0 : TEXCOORD0;
				float3 normal : NORMAL;
				float4 color : COLOR;
				
			};

			struct v2f
			{
    
    
				float2 uv : TEXCOORD0;
				float3 pos_World : TEXCOORD1;
				float3 normal_World : TEXCOORD2;
				float4 pos : SV_POSITION;
				float4 vertex_color : TEXCOORD3;
			};

			sampler2D _BaseMap,_SSSMap,_ILM,_DetailMap;
			float4 _BaseMap_ST,_SSSMap_ST,_ILM_ST,_DetailMap_ST;
			
			float _ToonTheshold,_ToonHardness,_SpecSzie;
			float _OutLineWidth;
			float4 _OutLineColor;
			float _OutlineZbias;
			v2f vert (appdata v)
			{
    
    
				v2f o;
				
				o.pos_World = mul(unity_ObjectToWorld,v.vertex).xyz;
				o.normal_World = UnityObjectToWorldNormal(v.normal);
				float3 tempDir = float3(o.normal_World);
				tempDir.z = _OutlineZbias * (1.0 - v.color.b);
				o.pos_World = o.pos_World + tempDir * _OutLineWidth * v.color.a;

				o.pos = mul(UNITY_MATRIX_VP,float4(o.pos_World,1.0));

				o.uv = v.texcoord0;
				o.vertex_color = v.color;
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{
    
    

				half2 uv1 = i.uv.xy;
				
				// base 主贴图
				float3 base_color = tex2D(_BaseMap,uv1).rgb;
				// 找出最亮的部分
				float maxComponent = max(max(base_color.r,base_color.g),base_color.b) - 0.004;
				float3 saturatedColor = step(maxComponent.rrr,base_color) * base_color;
				saturatedColor = lerp(base_color.rgb,saturatedColor,0.6);
				float3 outLineColor = 0.8 * saturatedColor * base_color * _OutLineColor.xyz;
				return float4(outLineColor,1.0);
			}
			ENDCG
		}
	}
}

任重而道远, 都是自己熟悉的最基础的知识 ,然而只能看别人写完的东西爽歪歪, 尤其是对贴图资源的把控,太需要补充了!!!

猜你喜欢

转载自blog.csdn.net/js0907/article/details/119222368