BlinnPhong 光照模型
一、来历和原理
1.来历
Blinn Phong 光照模型我们之前提到过,它是由吉姆·布林(jim Blinn,美国计算机科学家),在 1977 年时,在 Phong 光照模型基础上进行修改提出的 它和 Phong 一样是一个经验模型,并不符合真实世界中的光照现象 它们只是看起来正确
2.原理
Blinn Phong 和 Phong 光照模型一样,认为物体表面反射光线是由三部分组成的
环境光 +漫反射光 +镜面反射光(高光反射光)
二、公式
Phong 光照模型公式:
物体表面光照颜色环境光颜色 + 漫反射光颜色 + 高光反射光颜色
其中:
- 环境光颜色 = UNITY_LIGHTMODEL_AMBIENT(unity Ambientsky、unity AmbientEquator、unity AmbientGround)
- 漫反射光颜色 = 兰伯特光照模型 计算得到的颜色
- 高光反射光颜色= Blinn Phong 式高光反射光照模型 计算得到的颜色
三、顶点着色器的实现
1.实现步骤
- 属性声明(材质高光反射的颜色,光泽度)
- 渲染标签 Tags 的设置 将 LightMode 光照模式 设置为 ForwardBase 向前渲染(该模式通常用于不透明物体的基本渲染)
- 引用内置文件 "UnityCG.cginc" "UnityCG.cginc"
- 结构体声明
- 基本逻辑的实现
2.实例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70
| Shader "Unlit/BlinnPhong" { Properties { _MainColor("MainColor",Color) = (1,1,1,1) _SpecularColor("SpecularColor",Color) = (1,1,1,1) _SpecularNum("SpecularNum",Range(0,20)) = 0.5 } SubShader { Pass { Tags { "LightMode"="ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct v2f { float4 pos:SV_POSITION; fixed3 color:COLOR;
}; fixed4 _MainColor; fixed4 _SpecularColor; float _SpecularNum;
fixed3 GetLambertColor(float3 normal) { float3 WNnormal = UnityObjectToWorldNormal(normal); float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); fixed3 color = _MainColor * _LightColor0.rgb * max(0,dot(WNnormal,lightDir)); return color; } fixed3 GetBlinnPhongSpecularColor(float4 pos,float3 normal) { float3 worldPos = mul(UNITY_MATRIX_M,pos); float3 viewDir = _WorldSpaceCameraPos.xyz - worldPos; viewDir = normalize(viewDir);
float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); float3 wNormal = UnityObjectToWorldNormal(normal);
float3 halfA = normalize(viewDir +lightDir);
fixed3 color = _LightColor0.rgb * _SpecularColor.rgb * pow(max(0,dot(wNormal,halfA)),_SpecularNum); return color; } v2f vert (appdata_base v) { v2f v2fData; v2fData.pos = UnityObjectToClipPos(v.vertex); fixed3 LambertColor = GetLambertColor(v.normal); fixed3 SpecularColor = GetBlinnPhongSpecularColor(v.vertex,v.normal);
fixed3 color = UNITY_LIGHTMODEL_AMBIENT.rgb + LambertColor + SpecularColor; v2fData.color = color; return v2fData; }
fixed4 frag (v2f i) : SV_Target { return fixed4(i.color.rgb,1); } ENDCG } } }
|
3.实现效果

四、片元着色器的实现
1.实现步骤
- 属性声明(材质高光反射的颜色,光泽度)
- 渲染标签 Tags 的设置 将 LightMode 光照模式 设置为 ForwardBase 向前渲染(该模式通常用于不透明物体的基本渲染)
- 引用内置文件 "UnityCG.cginc" "UnityCG.cginc"
- 结构体声明
- 基本逻辑的实现
2.实例代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
| Shader "Unlit/BlinnPhongF" { Properties { _MainColor("MainColor",Color) = (1,1,1,1) _SpecularColor("SpecularColor",Color) = (1,1,1,1) _SpecularNum("SpecularNum",Range(0,20)) = 0.5 } SubShader {
Pass { Tags {"LightMode"="ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" struct v2f { float4 pos:SV_POSITION; float3 normal:NORMAL; float3 wPos:TEXCOORD0; }; v2f vert (appdata_base v) { v2f data; data.pos = UnityObjectToClipPos(v.vertex); data.normal = UnityObjectToWorldNormal(v.normal); data.wPos = mul(UNITY_MATRIX_M,v.vertex).xyz; return data; }
float3 _MainColor; fixed3 GetLambertFColor(in float3 normal) { float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); fixed3 color = _MainColor.rgb * _LightColor0.rgb * max(0,dot(lightDir,normal)); return color; }
float3 _SpecularColor; float _SpecularNum; fixed3 GetBlinnSpecularColor(in float3 wPos,in float3 normal) { float3 viewDir = normalize(_WorldSpaceCameraPos.xyz-wPos);
float3 lightDir = normalize(_WorldSpaceLightPos0).xyz;
float3 halfA = normalize(viewDir + lightDir);
fixed3 color = _LightColor0.rgb * _SpecularColor.rgb *pow(max(0,dot(halfA,normal)),_SpecularNum); return color; } fixed4 frag (v2f i) : SV_Target { fixed3 lambertColor = GetLambertFColor(i.normal); fixed3 SpecularColor = GetBlinnSpecularColor(i.wPos,i.normal); fixed3 color = UNITY_LIGHTMODEL_AMBIENT.rgb + lambertColor + SpecularColor; return fixed4(color.rgb , 1); } ENDCG } } }
|
3.实现效果
