Shader "ShaderCode/0301/Phone"
{
Properties
{
//漫反射贴图
_MainTex ("Texture", 2D) = "white" {}
//法线贴图
_NormalMap("NormalMap",2D)= "bump"{}
_NormalIntensity("NormalIntensity",Range(0,5)) =1
// Ao 贴图
_AOMap("AOMap",2D)="white"{}
// 高光遮罩图
_SpecMask("SpecMask",2D)="white"{}
_Shininess("Shininess",Range(0.01,100))=1
_AmbientColor("Ambient Color",Color)=(0,0,0,0)
_SpecInstensity("SpecInstensity",Range(0.01,5)) =1
}
SubShader
{
Tags { "RenderType"="Opaque" }
Pass
{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "AutoLight.cginc"
#include "UnityCG.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 _MainTex;
float4 _MainTex_ST;
sampler2D _AOMap;
sampler2D _SpecMask;
sampler2D _NormalMap;
float _NormalIntensity;
float4 _LightColor0;
float _Shininess;
float4 _AmbientColor;
half _SpecInstensity;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.normal_dir = normalize(mul(float4(v.normal,0),unity_WorldToObject).xyz);
o.tangent_dir = normalize(mul(unity_ObjectToWorld,float4(v.tangent.xyz,0))).xyz;
o.binormal_dir = cross(o.normal_dir,o.tangent_dir)*v.tangent.w;
o.pos_world = mul(unity_ObjectToWorld,v.vertex).xyz;
return o;
}
half4 frag (v2f i) : SV_Target
{
half4 base_color = tex2D(_MainTex, i.uv);
half4 ao_color = tex2D(_AOMap,i.uv);
half4 spec_mask = tex2D(_SpecMask,i.uv);
half4 normalmap = tex2D(_NormalMap,i.uv);
half3 normal_data= UnpackNormal(normalmap);
//NormalMap
half3 normal_dir = normalize(i.normal_dir);
half3 tangent_dir = normalize(i.tangent_dir);
half3 binormal_dir = normalize(i.binormal_dir);
// // 法线贴图计算 方式一
// normal_data.xy = normal_data.xy * _NormalIntensity;
// float3x3 TBM = float3x3(tangent_dir,binormal_dir,normal_dir);
// normal_dir = normalize(mul(TBM,normal_data));
// 法线贴图计算 方式二
normal_dir = normalize(tangent_dir*normal_data.x * _NormalIntensity + binormal_dir*normal_data.y* _NormalIntensity + normal_dir * normal_data.z);
half3 view_dir = normalize(_WorldSpaceCameraPos.xyz - i.pos_world);
half3 light_dir = normalize(_WorldSpaceLightPos0.xyz);
half NdotL = dot(normal_dir,light_dir);
half3 diffuse_color = max(0,NdotL) * _LightColor0.xyz * base_color;
half3 reflect_dir = reflect (-light_dir,normal_dir);
half RdotV = dot(reflect_dir,view_dir);
half3 spec_color = pow(max(0,RdotV),_Shininess)*_LightColor0.xyz *_SpecInstensity * spec_mask.rgb;
half3 final_color = (diffuse_color + spec_color + _AmbientColor.xyz) * ao_color;
return half4(final_color,1);
}
ENDCG
}
Pass
{
Tags{"LightMode"="ForwardAdd"}
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdadd
#include "AutoLight.cginc"
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
float3 normal:NORMAL;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 pos : SV_POSITION;
float3 normal_dir:TEXCOORD1;
float3 pos_world:TEXCOORD2;
};
sampler2D _MainTex;
float4 _MainTex_ST;
sampler2D _AOMap;
sampler2D _SpecMask;
float4 _LightColor0;
float _Shininess;
float4 _AmbientColor;
half _SpecInstensity;
v2f vert (appdata v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
o.normal_dir = normalize(mul(float4(v.normal,0),unity_WorldToObject).xyz);
o.pos_world = mul(unity_ObjectToWorld,v.vertex).xyz;
return o;
}
half4 frag (v2f i) : SV_Target
{
half4 base_color = tex2D(_MainTex, i.uv);
half4 ao_color = tex2D(_AOMap,i.uv);
half4 spec_mask = tex2D(_SpecMask,i.uv);
half3 normal_dir = normalize(i.normal_dir);
half3 view_dir = normalize(_WorldSpaceCameraPos.xyz - i.pos_world);
// 平行光
#if defined (DIRECTIONAL)
half3 light_dir = normalize(_WorldSpaceLightPos0.xyz);
half attenuation = 1.0;
// 点光源
#elif defined (POINT)
// 方向
half3 light_dir = normalize(_WorldSpaceLightPos0.xyz - i.pos_world);
// 距离
half distance = length(_WorldSpaceLightPos0.xyz - i.pos_world);
// 范围 点光源衰减
half range = 1/ unity_WorldToLight[0][0];
float attenuation = saturate((range-distance)/range);
#endif
half NdotL = dot(normal_dir,light_dir);
half3 diffuse_color = max(0,NdotL) * _LightColor0.xyz * base_color * attenuation;
half3 reflect_dir = reflect (-light_dir,normal_dir);
half RdotV = dot(reflect_dir,view_dir);
half3 spec_color = pow(max(0,RdotV),_Shininess)*_LightColor0.xyz *_SpecInstensity * spec_mask.rgb;
half3 final_color = (diffuse_color + spec_color) * ao_color;
return half4(final_color,1);
}
ENDCG
}
}
}