COS_NPR非真实渲染_头发

一个非真实渲染的头发

只有简单的两部分,因为是打包手表,所以尽量简洁了

漫反射(可控背影颜色)+高光反射(各向异性+扰乱)

效果:

COS_NPR非真实渲染_头发_第1张图片

COS_NPR非真实渲染_头发_第2张图片

COS_NPR非真实渲染_头发_第3张图片

参考崩坏的想法:

COS_NPR非真实渲染_头发_第4张图片

COS_NPR非真实渲染_头发_第5张图片

所用的扰乱贴图:

代码:

// Upgrade NOTE: replaced '_Object2World' with 'unity_ObjectToWorld'
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'


//非真实渲染_头发

Shader "ABigDeal/COS_AnistotrpicHair" {
	Properties {
		_MainTex("Main Tex", 2D) = "white" {}                 //主贴图
		_Color ("Color Tint", Color) = (1, 1, 1, 1)           //头发颜色
		_DiffuseColor("Diffuse Color", Color) = (1, 1, 1, 1)  //漫反射颜色 

		_BumpMap ("Normal Map", 2D) = "bump" {}              //法线贴图
		_BumpScale ("Bump Scale", Float) = 1.0               //法线贴图程度
		_AnisMap("Anisotripic Map", 2D) = "bump" {}          //扰乱贴图
		
		_AnisLowScale("Anisotripic Low Scale", Float) = 1.0 //底层扰乱程度 
		_SpeLowColor("Specular", Color) = (1, 1, 1, 1)      //底层反射颜色
		_SpeLowGloss ("Specular Low Gloss", Range(0.01, 50)) = 0.3//底层反射范围
		_SpeLowStrength("Specualr Low StrengthA",Range(0,1)) = 0.5  //底层反射强度
		_SpeLowOffset("Anisotropic Offset",Range(0,2)) = 1.5  //底层反射各向异性的偏移

		_AnisHigScale("Anisotripic Hig Scale", Float) = 1.0//高层扰乱程度
		_SpeHigColor("Specular", Color) = (1, 1, 1, 1)     //高层反射颜色
		_SpeHigGloss("Specular Low Gloss", Range(0.01, 20)) = 0.3   //高层反射范围
		_SpeHigStrength("Specualr Low StrengthA",Range(0,1)) = 0.5  //高光反射强度
		_SpeHigOffset("Anisotropic Offset",Range(0,2)) = 1.5  //高层反射各向异性的偏移



	}
	SubShader {
		Pass { 
			Tags { "LightMode"="ForwardBase" }
			Cull Back
			ZTest LEqual
			CGPROGRAM
			
			#pragma vertex vert
			#pragma fragment frag
			
			#include "Lighting.cginc"
            #include "AutoLight.cginc"
			
			fixed4 _Color;
			fixed4 _DiffuseColor;
			sampler2D _MainTex;
			float4 _MainTex_ST;
			sampler2D _BumpMap;
			float4 _BumpMap_ST;
			sampler2D _AnisMap;
			float _BumpScale;
			fixed4 _SpeLowColor;
			float _SpeLowGloss;
			float _SpeLowStrength;
			float _SpeLowOffset;
			float _AnisLowScale;

			fixed4 _SpeHigColor;
			float _SpeHigGloss;
			float _SpeHigStrength;
			float _SpeHigOffset;
			float _AnisHigScale;

			struct a2v {
				float4 vertex : POSITION;
				float3 normal : NORMAL;
				float4 tangent : TANGENT;
				float4 texcoord : TEXCOORD0;
			};
			
			struct v2f {
				float4 pos : SV_POSITION;
				float4 uv : TEXCOORD0;
				float4 TtoW0 : TEXCOORD1;  
				float4 TtoW1 : TEXCOORD2;  
				float4 TtoW2 : TEXCOORD3; 
				float3 worldPos : TEXCOORD4;
			};
			
			v2f vert(a2v v) {
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				
				o.uv.xy = v.texcoord.xy * _MainTex_ST.xy + _MainTex_ST.zw;
				o.uv.zw = v.texcoord.xy * _BumpMap_ST.xy + _BumpMap_ST.zw;
				
				float3 worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;  
				fixed3 worldNormal = UnityObjectToWorldNormal(v.normal);  
				fixed3 worldTangent = UnityObjectToWorldDir(v.tangent.xyz);  
				fixed3 worldBinormal = cross(worldNormal, worldTangent) * v.tangent.w; 
				
				// Compute the matrix that transform directions from tangent space to world space
				// Put the world position in w component for optimization
				o.TtoW0 = float4(worldTangent.x, worldBinormal.x, worldNormal.x, worldPos.x);
				o.TtoW1 = float4(worldTangent.y, worldBinormal.y, worldNormal.y, worldPos.y);
				o.TtoW2 = float4(worldTangent.z, worldBinormal.z, worldNormal.z, worldPos.z);
				
				o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;

				return o;
			}
			//使用从切线空间转换到世界空间的法线
			fixed4 frag(v2f i) : SV_Target {
			
				float3 worldPos = float3(i.TtoW0.w, i.TtoW1.w, i.TtoW2.w);	// 获得世界空间下的坐标

				fixed3 albedo = tex2D(_MainTex, i.uv).rgb * _Color.rgb;//采样漫反射贴图
				
				//////////【法线】
				fixed3 N = UnpackNormal(tex2D(_BumpMap, i.uv.zw));//采样法线贴图
				N.xy *= _BumpScale;                                //法线*程度
				N.z = sqrt(1.0 - saturate(dot(N.xy, N.xy)));//求法线的Z
				N = normalize(half3(dot(i.TtoW0.xyz, N), dot(i.TtoW1.xyz, N), dot(i.TtoW2.xyz, N))); //把法线从切线空间转换到世界空间
				
				 ///////【扰乱贴图】
				float3 ALow = UnpackNormal(tex2D(_AnisMap, i.uv.zw));//采样扰乱贴图
				       ALow.y *= _AnisLowScale;                      //*底层的扰乱程度
				float3 AHig = UnpackNormal(tex2D(_AnisMap, i.uv.zw));//采样扰乱贴图
				       AHig.y *= _AnisHigScale;                      //*高层的扰乱程度

				fixed3 L = normalize(UnityWorldSpaceLightDir(worldPos));//【lightDir】 把光照方向转换到世界空间下
				fixed3 V = normalize(UnityWorldSpaceViewDir(worldPos));//【viewDir】 把视角方向转换到世界空间下
				fixed3 H = normalize(L + V);//【half】半兰伯特
			    float3 T = 0 / N;//【切线】 法线与切线垂直
				       T.y = T.y - 50;//偏移一点
				
				float NdotL = saturate(dot(N, L));//【法线/光线点积】
				float TdotL = saturate(dot(T, L));//【切线/光线点击】
			     
				//半兰伯特*切线(其中切线被扰乱了)
				fixed HdotALow = dot(normalize(T + ALow + N), H);//dot((H+N+A),H)
				fixed HdotAHig = dot(normalize(T + AHig+ N), H);
				
				
				///////【环境色】  ambient
				fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * albedo;
				
				///////【漫反射】diffuse
				float Dif = saturate(lerp(0.25, 1.0, NdotL));//保证亮度,修改NdotT取值域
				fixed3 diffuse = (Dif + ambient)*albedo.rgb;// albedo *  NdotL;
				diffuse = lerp(_DiffuseColor.rgb*diffuse, diffuse, NdotL);
				
				///////【光照衰减】 atten
				UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos);
				atten = saturate(atten);
				
				///////Sin的各向异性
				float anisoLow = max(0, sin(radians((HdotALow + _SpeLowOffset) *180)));
				float specLow = saturate(pow(anisoLow, _SpeLowGloss * 128)*_SpeLowStrength);
				float3 SpeColorLow = specLow*_SpeLowColor.rgb;
				float anisoHig = max(0, sin(radians((HdotAHig + _SpeHigOffset) * 180)));
				float specHig = saturate(pow(anisoHig, _SpeHigGloss * 128)*_SpeHigStrength);
				
				///////【反射】Specular
				float3 Specular = ((SpeColorLow + specHig *_SpeHigColor.rgb))* NdotL;

				fixed4 c;
				c.rgb = _LightColor0.rgb *(diffuse + Specular);// *(atten * 1.3);

				c.a = 1.0;
				return c;
	
			}
			
			ENDCG
		}
} 
	FallBack "Specular"
}

 

 

 

 

 

你可能感兴趣的:(ABigDeal的小宝库)