一个非真实渲染的头发
只有简单的两部分,因为是打包手表,所以尽量简洁了
漫反射(可控背影颜色)+高光反射(各向异性+扰乱)
效果:
参考崩坏的想法:
所用的扰乱贴图:
代码:
// 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"
}