一.图形学颜色叠加乘法(各分量相乘)
light(1, 1, 1) * stuff(0.2f, 0.3f, 0.5f) = (0.2f, 0.3f, 0.5f)
二.经验模型Phong
Phong = Ambient + Diffuse +Specular
1.Diffuse漫反射
Diffuse = dot ( -lightDir , N) * lightColor
这里点乘: dot( A , B) =|A| |B| Cos<A,B> ,所以夹角越小,diffuse越大;
Diffuse 兰伯特光照模型:
Shader "Unlit/Lambert"
{
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float3 worldNormal:TEXCOORD0;
float4 vertex : SV_POSITION;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//法线N
fixed3 worldNormal = normalize(i.worldNormal);
//光源方向LightDir
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
//diffuse分量计算
fixed3 diffuse = max(0.0, dot(worldNormal, -worldLightDir));
//叠加光源色
fixed3 diffuseColor = diffuse * _LightColor0.xyz;
return fixed4(diffuseColor, 0);
}
ENDCG
}
}
}
2.Specular镜面反射
Specular = pow (max( 0 , dot(ReflectDir, ViewDir) ) , Glass) * lightColor;
反射方向用CG函数 reflect(L , N)计算;
ViewDir = normalize( _WorldSpaceCameraPos.xyz - i.worldPos); //i为v2f
加入Specular之后的Shader:
Shader "Unlit/Phong"
{
Properties{
_SpecularGlass("SpecularGlassStrength", Range(0,64))=32
}
SubShader
{
Tags { "RenderType" = "Opaque" }
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
#include "Lighting.cginc"
struct appdata
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float3 worldNormal:NORMAL;
float4 vertex : SV_POSITION;
float3 worldPos : TEXCOORD1;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
o.worldPos = mul(unity_ObjectToWorld, v.vertex).xyz;
return o;
}
float _SpecularGlass;
fixed4 frag (v2f i) : SV_Target
{
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = max(0.0, dot(worldNormal, -worldLightDir));
fixed3 diffuseColor = diffuse * _LightColor0.xyz;
//计算reflect方向
fixed3 reflectDir = normalize(reflect(worldLightDir, worldNormal));
//计算view方向
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos);
//specular分量
fixed3 specular = pow(max(0.0, dot(reflectDir, viewDir)), _SpecularGlass);
fixed3 specularColor = specular * _LightColor0.xyz;
return fixed4(diffuseColor + specularColor, 0);
}
ENDCG
}
}
}
3.Ambient环境光
环境光之间获取 乘上叠加物体颜色;
//环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz * _ObjColor;
给一个Obj颜色之后: