半兰伯特光照模型
一、必备知识
单位向量的点乘范围
根据数学公式我们知道 假设单位向量 A 和 B,他们的点乘结果是 A·B=|A|*|B|*cosθ 因为 cosθ 的范围是(-1,,1)之间,所以单位向量的点乘范围也是(-1,1)
二、半兰伯特光照模型的来历和原型
半兰伯特光照模型是基于 兰伯特光照模型的基础上进行改进的 它没有任何物理依据,只是一个视觉加强技术 它出现的主要原因是因为我们在使用兰伯特光照模型时,在背光面是全黑的 而半兰伯特光照模型可以让背光面也可以有明暗变化
半兰伯特光照模型没有特定的发明者 它是图形学领域的众多研究人员的共同贡献 研究人员们经常相互借鉴和改进现有模型 以更好的模拟真实世界中的光照和材质反射
原理 和兰伯特光照模型的理论是一样的 认为漫反射的强度仅仅与入射光的 方向和反射点处表面法线的夹角的余弦值成正比
三、半兰伯特光照模型的公式
1.公式
漫反射光照颜色 = 光源的颜色 * 材质的漫反射颜色 * ((标准化后物体表面法线向量 · 标准化后光源方向向量) * 0.5 + 0.5)
2.对比
兰伯特光照模型 :光源的颜色 * 材质的漫反射颜色 * max(0 , 标准化后物体表面法线向量 · 标准化后光源方向向量) 后半部分 点乘小于 0 部分会变成 0 半兰伯特光照模型:光源的颜色 * 材质的漫反射颜色 * ((标准化后物体表面法线向量 · 标准化后光源方向向量) * 0.5 + 0.5) 后半部分 点乘小于 0 部分都会变成 0~0.5
四、顶点着色器实现
1.代码部分
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
| Shader "Unlit/Hanf_Lambert" { Properties { _MainColor("MainColor",Color) = (1,1,1,1) } SubShader { Tags { "LightMode"="ForwardBase" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" fixed4 _MainColor; struct v2f { float4 pos:SV_POSITION; fixed3 color:COLOR;
};
v2f vert (appdata_base v) { v2f v2fData; v2fData.pos = UnityObjectToClipPos(v.vertex); float3 normal = UnityObjectToWorldNormal(v.normal); float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); v2fData.color = UNITY_LIGHTMODEL_AMBIENT.rgb + _LightColor0.rgb * _MainColor *(dot(normal,lightDir)*0.5+0.5); return v2fData; }
fixed4 frag (v2f i) : SV_Target { return fixed4(i.color.rgb,1); } ENDCG } } }
|
2.实现效果
实现效果图
四、片元着色器实现
1.代码部分
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
| Shader "Unlit/Harf_LambertF" { Properties { _MainColor("MainColor",Color) = (1,1,1,1) } SubShader { Tags { "LightMode"="ForwardBase" } Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #include "Lighting.cginc" float4 _MainColor; struct v2f { float4 pos:SV_POSITION; float3 normal:NORMAL; }; v2f vert (appdata_base v) { v2f v2fData; v2fData.pos = UnityObjectToClipPos(v.vertex); v2fData.normal = UnityObjectToWorldNormal(v.normal); return v2fData; }
fixed4 frag (v2f i) : SV_Target { float3 lightDir = normalize(_WorldSpaceLightPos0.xyz); fixed3 color = _MainColor.rgb * _LightColor0.rgb * (dot(i.normal,lightDir)*0.5+0.5); color = UNITY_LIGHTMODEL_AMBIENT.rgb + color; return fixed4(color.rgb,1); } ENDCG } } }
|
2.实现效果
实现效果图