朗伯定理
Shader "Shenjun/FragmentLight_Specular" {
Properties {
_MainTex ("Base (RGB)", 2D) = "white" {}
_BumpTex ("Bump", 2D) = ""{}
_SpecularColor ("SpecularColor", Color) = (1,1,1,1)
_Shininess ("Shininess", float) = 10.0
}
SubShader {
Tags { "RenderType"="Opaque" }
LOD 200
Pass
{
Tags { "LightMode"="ForwardBase" }
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
sampler2D _MainTex;
sampler2D _BumpTex;
float4 _SpecularColor;
float _Shininess;
struct v2f
{
float4 pos : POSITION;
fixed2 uv : TEXCOORD;
float3 normalWorld : TEXCOORD1;
float3 posWorld : TEXCOORD2;
float4 tangentWorld : TEXCOORD3;
};
v2f vert(appdata_tan input)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, input.vertex);
o.uv = input.texcoord;
o.normalWorld = mul((float3x3)_Object2World, input.normal);
o.posWorld = mul(_Object2World, input.vertex);
o.tangentWorld = mul(_Object2World, input.tangent);
return o;
}
void frag(v2f input, out float4 col : COLOR)
{
col = tex2D(_MainTex, input.uv);
// 计算法线的效果
//float4 encodeNormal = tex2D(_BumpTex, input.uv);
//float3 localTexcoord = float3(2 * encodeNormal.a - 1, 2 * encodeNormal.g - 1, 0);
//localTexcoord.z = sqrt(1 - dot(localTexcoord, localTexcoord));
//float3 biNormalDir = cross (input.normalWorld, input.tangentWorld * input.tangentWorld.w);
//float3x3 TBN = float3x3((float3)input.tangentWorld, biNormalDir, input.normalWorld);
//float3 N = normalize(mul(localTexcoord, TBN));
float3 N = UnpackNormal(tex2D(_BumpTex, input.uv));
// diffuseColor = C * max(0, dot(N, L))
// float3 N = normalize(input.normalWorld);
float3 L;
float atten;
if(_WorldSpaceLightPos0.w == 0)
{
atten = 1;
L = normalize(_WorldSpaceLightPos0);
}
else
{
float3 vertex2Light = _WorldSpaceLightPos0.xyz - input.posWorld;
L = normalize(vertex2Light);
float fLenght = length(vertex2Light);
atten = 1 / fLenght;
}
float3 C = atten * _LightColor0.rgb;
float3 diffuseColor = C * max(0, dot(N, L));
float3 R = normalize(reflect(-L, N));
float3 V = normalize(_WorldSpaceCameraPos.xyz - input.posWorld);
float3 SpecularColor = C * _SpecularColor.rgb * pow(max(0, dot(R, V)), _Shininess);
col.rgb *= diffuseColor;
col.rgb += SpecularColor;
}
ENDCG
} // end pass
}
FallBack "Diffuse"
}
阴影渲染
Shader "Shenjun/Diffuse"
{
Properties
{
_DiffuseTexture ("Diffuse Texture", 2D) = "white" {}
_DiffuseTint ( "Diffuse Tint", Color) = (1, 1, 1, 1)
}
SubShader
{
Tags { "RenderType"="Opaque" }
pass
{
Tags { "LightMode"="ForwardBase"}
CGPROGRAM
#pragma target 3.0
#pragma fragmentoption ARB_precision_hint_fastest
#pragma vertex vertShadow
#pragma fragment fragShadow
#pragma multi_compile_fwdbase
#include "UnityCG.cginc"
#include "AutoLight.cginc"
sampler2D _DiffuseTexture;
float4 _DiffuseTint;
float4 _LightColor0;
struct v2f
{
float4 pos : SV_POSITION;
float3 lightDir : TEXCOORD0;
float3 normal : TEXCOORD1;
float2 uv : TEXCOORD2;
LIGHTING_COORDS(3, 4)
};
v2f vertShadow(appdata_base v)
{
v2f o;
o.pos = mul(UNITY_MATRIX_MVP, v.vertex);
o.uv = v.texcoord;
o.lightDir = normalize(ObjSpaceLightDir(v.vertex));
o.normal = normalize(v.normal).xyz;
TRANSFER_VERTEX_TO_FRAGMENT(o);
return o;
}
float4 fragShadow(v2f i) : COLOR
{
float3 L = normalize(i.lightDir);
float3 N = normalize(i.normal);
float attenuation = LIGHT_ATTENUATION(i) * 2;
float4 ambient = UNITY_LIGHTMODEL_AMBIENT * 2;
float NdotL = saturate(dot(N, L));
float4 diffuseTerm = NdotL * _LightColor0 * _DiffuseTint * attenuation;
float4 diffuse = tex2D(_DiffuseTexture, i.uv);
float4 finalColor = (ambient + diffuseTerm) * diffuse;
return finalColor;
}
ENDCG
}
}
FallBack "Diffuse"
}