效果:
代码:
Shader "MyShader/PhongNormal"
{
Properties
{
_DiffuseTex("漫反射贴图",2d)="white"{}
_AOTex("AO贴图",2d)="white"{}
_SpecularMask("高光遮罩",2d)="white"{}
_NormalMap("法线贴图",2d)="white"{}
_NormalIntensity("凹凸程度",Range(0.0,10))=1.0
_Shinesss("高光光滑度",float)=1.0
_ShinIntensity("高光亮度",Range(0.0,10.0))=1.0
}
SubShader
{
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{
Tags{"LightMode"="ForwardBase"}
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdbase
#include "UnityCG.cginc"
#include "AutoLight.cginc"
#include "Lighting.cginc"
float _Shinesss;
float _ShinIntensity;
float _NormalIntensity;
sampler2D _DiffuseTex;
float4 _DiffuseTex_ST;
sampler2D _AOTex;
sampler2D _SpecularMask;
sampler2D _NormalMap;
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
float4 tangent : TANGENT;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 worldNormal_Dir : TEXCOORD1;
float3 worldPos : TEXCOORD2;
float2 uv : TEXCOORD3;
float3 worldTangent_Dir : TEXCOORD4;
float3 worldBinormal_Dir : TEXCOORD5;
SHADOW_COORDS(6)
};
v2f vert (appdata v)
{
v2f o = (v2f)0;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal_Dir = normalize(mul(v.normal,unity_WorldToObject).xyz);
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
o.uv = TRANSFORM_TEX(v.texcoord,_DiffuseTex);
o.worldTangent_Dir = normalize(mul(unity_ObjectToWorld,v.tangent).xyz);
o.worldBinormal_Dir = normalize(cross(o.worldNormal_Dir,o.worldTangent_Dir))*v.tangent.w;
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
half4 frag (v2f i) : SV_Target
{
half4 diffuseColor = tex2D(_DiffuseTex,i.uv);
half4 AOMask = tex2D(_AOTex,i.uv);
half4 specularMask = tex2D(_SpecularMask,i.uv);
half4 normalMap = tex2D(_NormalMap,i.uv);
half3 normalMap_data = UnpackNormal(normalMap);
half shadow = LIGHT_ATTENUATION(i);
//Normal Map
half3 worldNormal_Dir = normalize(i.worldNormal_Dir);
half3 worldTangent_Dir = normalize(i.worldTangent_Dir);
half3 worldBinormal_Dir = normalize(i.worldBinormal_Dir);
worldNormal_Dir = normalize(worldTangent_Dir*normalMap_data.x*_NormalIntensity+worldBinormal_Dir*normalMap_data.y*_NormalIntensity+worldNormal_Dir*normalMap_data.z);
half3 worldView_Dir = normalize(_WorldSpaceCameraPos.xyz-i.worldPos);
half3 worldLight_Dir = normalize(_WorldSpaceLightPos0.xyz);
half3 reflect_Dir = normalize(reflect(-worldLight_Dir,worldNormal_Dir));
half NdotL = dot(worldNormal_Dir,worldLight_Dir);
half RdotV = dot(reflect_Dir,worldView_Dir);
half diffterm = min(max(0.0,NdotL),shadow);
half3 diffuse = diffterm*_LightColor0.xyz*diffuseColor.xyz;
half3 specular = pow(max(0.0,RdotV),_Shinesss)*_LightColor0.xyz*_ShinIntensity*specularMask.rgb*diffterm;
half3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz*diffuse*AOMask;
half3 final_color = diffuse+specular+ambient;
return half4(final_color,1.0);
}
ENDCG
}
Pass
{
Tags{"LightMode"="ForwardAdd"}
Blend One One
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile_fwdadd
#include "UnityCG.cginc"
#include "AutoLight.cginc"
#include "Lighting.cginc"
float _Shinesss;
float _ShinIntensity;
float _NormalIntensity;
sampler2D _DiffuseTex;
float4 _DiffuseTex_ST;
sampler2D _AOTex;
sampler2D _SpecularMask;
sampler2D _NormalMap;
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
float2 texcoord : TEXCOORD0;
float4 tangent : TANGENT;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 worldNormal_Dir : TEXCOORD1;
float3 worldPos : TEXCOORD2;
float2 uv : TEXCOORD3;
float3 worldTangent_Dir : TEXCOORD4;
float3 worldBinormal_Dir : TEXCOORD5;
LIGHTING_COORDS(6,7)
};
v2f vert (appdata v)
{
v2f o = (v2f)0;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal_Dir = normalize(mul(v.normal,unity_WorldToObject).xyz);
o.worldPos = mul(unity_ObjectToWorld,v.vertex).xyz;
o.uv = TRANSFORM_TEX(v.texcoord,_DiffuseTex);
o.worldTangent_Dir = normalize(mul(unity_ObjectToWorld,v.tangent).xyz);
o.worldBinormal_Dir = normalize(cross(o.worldNormal_Dir,o.worldTangent_Dir))*v.tangent.w;
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
half4 frag (v2f i) : SV_Target
{
half4 diffuseColor = tex2D(_DiffuseTex,i.uv);
half4 specularMask = tex2D(_SpecularMask,i.uv);
half4 normalMap = tex2D(_NormalMap,i.uv);
half3 normalMap_data = UnpackNormal(normalMap);
half shadowAtte = LIGHT_ATTENUATION(i);
//Normal Map
half3 worldNormal_Dir = normalize(i.worldNormal_Dir);
half3 worldTangent_Dir = normalize(i.worldTangent_Dir);
half3 worldBinormal_Dir = normalize(i.worldBinormal_Dir);
worldNormal_Dir = normalize(worldTangent_Dir*normalMap_data.x*_NormalIntensity+worldBinormal_Dir*normalMap_data.y*_NormalIntensity+worldNormal_Dir*normalMap_data.z);
half3 worldView_Dir = normalize(_WorldSpaceCameraPos.xyz-i.worldPos);
#if defined(DIRECTIONAL)
half3 worldLight_Dir = normalize(_WorldSpaceLightPos0.xyz);
#elif defined(POINT)
half3 worldLight_Dir = normalize(_WorldSpaceLightPos0.xyz-i.worldPos);
#endif
half3 reflect_Dir = normalize(reflect(-worldLight_Dir,worldNormal_Dir));
half NdotL = dot(worldNormal_Dir,worldLight_Dir);
half RdotV = dot(reflect_Dir,worldView_Dir);
half diffterm = min(max(0.0,NdotL),shadowAtte);
half3 diffuse = diffterm*_LightColor0.xyz*diffuseColor.xyz;
half3 specular = pow(max(0.0,RdotV),_Shinesss)*_LightColor0.xyz*_ShinIntensity*specularMask.rgb*shadowAtte;
half3 final_color = diffuse+specular;
return half4(final_color,1.0);
}
ENDCG
}
}
FallBack "Diffuse"
}