当前位置:   article > 正文

【KaJiYa改进】Shader头发效果_unity头发hairtools

unity头发hairtools

感谢原作者,链接见转载。
头发各项异性高光:该shader需使用三张texture进行合成,可以像KaJiYa调节光照环,另外也可以调节Tilling影响发丝,立方体纹理影响整体效果。

在这里插入图片描述

Shader "Unlit/CharHair"
{
	Properties
	{
		_BaseMap ("BaseMap", 2D) = "white" {}
		_CompMask ("ComMase", 2D) = "white" {}
		_NormalMap("bumpMap",2D) = "bump"{}
		_SpecIntensity("_SpecIntensity",Range(0,20))= 1
		_SpecShininess("_SpecShininess",Range(0,20))= 1

		[Header(IBL)]
		_EvnMap("cube map",Cube) = "white"{}
		_Tint("tint",Color) = (1,1,1,1)
		_Expose("Expose",float) = 1
		_Rotate("Rotate",Range(0,360)) = 0


[Header(Aniso)]
		_AnisoMap("anis",2D) = "gray"{}

		_SpecColor1("specColor 1",Color) = (1,1,1,1)
		_SpecShininess1("_SpecShininess 1",Range(0,1)) = 0.1
		_SpecNoise1("_SpecNoise1",float) = 1
		_SpecOffset1("_Specffset1",float) = 0

		_SpecColor2("specColor 2",Color) = (1,1,1,1)
		_SpecShininess2("_SpecShininess 2",Range(0,1)) = 0.1
		_SpecNoise2("_SpecNoise 2",float) = 1
		_SpecOffset2("_Specffset 2",float) = 0


_RoughnessAdjust("_RoughnessAdjust",Range(0,1)) = 1

	}
	SubShader
	{
		Tags { "RenderType"="Opaque" }
		LOD 100

		Pass
		{
			Tags{ "LightMode"="ForwardBase"}
			CGPROGRAM
			#pragma vertex vert
			#pragma fragment frag
			#pragma multi_compile_fwdbase

			// 这是两种写法 
			#pragma shader_feature _SPECCHECK_ON
			#pragma multi_compilr _ _IBLCHECK_ON
			
			#include "UnityCG.cginc"
			#include "AutoLight.cginc"
			#include "Lighting.cginc"
			struct appdata
			{
				float4 vertex : POSITION;
				float2 texcoord : TEXCOORD0;
				float3 normal : NORMAL;
				float4 tangent : TANGENT;
			};

			struct v2f
			{
				float2 uv : TEXCOORD0;
				float4 pos : SV_POSITION;
				float3 pos_world : TEXCOORD1;

				float3 normal_dir : TEXCOORD2;
				float3 tangent_dir : TEXCOORD3;
				float3 binormal_dir : TEXCOORD4;
			};

			sampler2D _BaseMap;
			float4 _BaseMap_ST;
			sampler2D _NormalMap;
			
			float _SpecShininess;
			float4 _SpecIntensity;
			
			float _RoughnessAdjust;
			// ibl
			samplerCUBE _EvnMap;
			float4 _EvnMap_HDR;
			float4 _Tint;
			float _Expose;

			//  aniso
			sampler2D _AnisoMap;
			float4 _AnisoMap_ST;
			float4 _SpecColor1;
			float _SpecNoise1;
			float _SpecShininess1;
			float _SpecOffset1;

						
			float4 _SpecColor2;
			float _SpecNoise2;
			float _SpecShininess2;
			float _SpecOffset2;
			
			v2f vert (appdata v)
			{
				v2f o;
				o.pos = UnityObjectToClipPos(v.vertex);
				o.uv = TRANSFORM_TEX(v.texcoord, _BaseMap);
				o.normal_dir = normalize(UnityObjectToWorldNormal(v.normal));
				o.tangent_dir = normalize(UnityObjectToWorldDir(v.tangent.xyz));
				o.binormal_dir = normalize(cross(o.normal_dir, o.tangent_dir)) * v.tangent.w;
				o.pos_world	= mul(unity_ObjectToWorld,v.vertex).xyz;
				
				return o;
			}
			
			fixed4 frag (v2f i) : SV_Target
			{

				fixed4 base_color_ = tex2D(_BaseMap, i.uv);
				fixed4 base_color = base_color_;
				fixed4 spec_color = base_color_;
				half roughtness = saturate(_RoughnessAdjust);
				fixed3 normal_data = UnpackNormal(tex2D(_NormalMap,i.uv));


				half3 light_dir = normalize(UnityWorldSpaceLightDir(i.pos_world));
				half3 view_dir = normalize(UnityWorldSpaceViewDir(i.pos_world));
				
				half3 normal_dir = normalize(i.normal_dir);
				half3 tangent_dir = normalize(i.tangent_dir);
				half3 binormal_dir = normalize(i.binormal_dir);
				
				float3x3 TBN = float3x3(tangent_dir,binormal_dir,normal_dir);
				normal_dir = normalize(mul(normal_data.xyz,TBN));

				
				// Direct diffuse 直接光漫反射
				//half diff_term = saturate(dot(light_dir,normal_dir));
				half diff_term = dot(light_dir,normal_dir);
				// 半兰伯特模型: 将【-1,1】 映射到【0,1】,  对于负数(背光面),也会右明暗变化!!!!!!
				half half_lambert = (diff_term + 1) * 0.5;
				half direct_diffuse = diff_term * _LightColor0.xyz * base_color.xyz;

				//Direct specular 直接光 镜面反射
				half2 uv_aniso = i.uv * _AnisoMap_ST.xy + _AnisoMap_ST.zw;
				half aniso_noise = tex2D(_AnisoMap,uv_aniso).r - 0.5;

				half3 half_dir = normalize(light_dir + view_dir);
				half NdotH = saturate(dot(normal_dir,half_dir));
				half TdotH = dot(tangent_dir,half_dir);
				half NdotV = saturate(dot(view_dir,normal_dir));

				// 求出各项异性高光的 衰减值 
				float aniso_atten = saturate(sqrt(saturate(half_lambert/NdotV)));
				// spec1
				//  加上baseColor  ,有一个渐变的过渡
				float3 spec_color1 = _SpecColor1.rgb + base_color;

				float3 aniso_offset1 = normal_dir * (aniso_noise * _SpecNoise1 + _SpecOffset1);

				binormal_dir = normalize(binormal_dir + normal_dir * aniso_offset1);
				// 除以光滑度
				float BdotH1 = dot(binormal_dir,half_dir)/ _SpecShininess1;

				// float3 kajiya = sqrt(1 - BdotH1 * BdotH1)
				float spec_term1 = exp(-(TdotH * TdotH + BdotH1 * BdotH1)/ (1+ NdotH));
				float3 final_spec1 = spec_term1 * aniso_atten * spec_color1 * _LightColor0.xyz;

				// spec2
				float3 spec_color2 = _SpecColor2.rgb + base_color;
				float3 aniso_offset2 = normal_dir * (aniso_noise * _SpecNoise2 + _SpecOffset2);
				binormal_dir = normalize(binormal_dir + normal_dir * aniso_offset2);
				float BdotH2 = dot(binormal_dir,half_dir)/ _SpecShininess2;
				float spec_term2 = exp(-(TdotH * TdotH + BdotH2 * BdotH2)/ (1+ NdotH));
				float3 final_spec2 = spec_term2 * aniso_atten * spec_color2 * _LightColor0.xyz;


				// 正常的镜面反射
				// half3 half_dir = normalize(light_dir + view_dir);
				// half NdotH = saturate(dot(normal_dir,half_dir));
				// half smoothness = 1- roughtness;
				// half shininess = lerp(1,_SpecShininess,smoothness);
				// half spec_term = pow(NdotH,shininess);
				// half3 direct_specular = spec_term * spec_color * _LightColor0.rgb * _SpecIntensity;



				// InDirect spec 间接光镜面反射
				float3 reflect_dir = reflect(-view_dir,normal_dir);

				roughtness = roughtness * (1.7 - 0.7 * roughtness);
				float mip_level = roughtness * 6;
				half4 color_cubemap = texCUBElod(_EvnMap,float4(reflect_dir,mip_level));
				float3 evn_color = DecodeHDR(color_cubemap,_EvnMap_HDR);
				// 用系数 乘以 金属色
				half3 evn_specular = evn_color * _Expose * spec_color;
				
				//float3 final_color = direct_diffuse + direct_specular  + evn_specular;
				float3 final_color = direct_diffuse + final_spec2 + final_spec1 + evn_specular;

				

				return fixed4(final_color,1);
			}
			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
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号