0%

unity基本光照模型实现

Lambert模型(漫反射)
1 和法线,光照有关

下面unity实现的例子 片元着色器中的:

1
2
3
4
5
6
7
8
9
10
11
12
//UNITY_LIGHTMODEL_AMBIENT 表示系统的环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

// Get the normal in world space
fixed3 worldNormal = normalize(i.worldNormal);
//得到世界空间中的光线方向
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);

// Compute diffuse term
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));

fixed3 color = ambient + diffuse;

Phong模型(镜面反射)
1 和视线,反射光照有关

下面unity实现的例子 片元着色器中的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//获取环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

//获取世界空间法线
fixed3 worldNormal = normalize(i.worldNormal);
//获取世界空间光照方向
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);

//计算漫反射
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));

//获取世界空间反射方向
fixed3 reflectDir = normalize (reflect(-worldLightDir, worldNormal));
//"reflect()" 函数是Unity内置的函数,可以用来计算反射方向,如果不使用这个函数则上一句代码可以改成下面这样:
//fixed3 reflectDir = normalize(-worldLightDir - 2 * dot(-worldNormal, worldLightDir) * worldNormal);

//获取世界空间中的视角方向
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
//计算反射信息
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir,viewDir)), _Gloss);

return fixed4(ambient + diffuse + specular, 1.0);

Blinn-Phong光照模型(修正镜面光)
1 和法线,半程向量有关

下面unity实现的例子 片元着色器中的:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//获取环境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;

//获取法线信息
fixed3 worldNormal = normalize(i.worldNormal);

//获取光线方向
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);

//计算漫反射信息
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));

//获取世界空间视角方向
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);

//计算Half方向
fixed3 halfDir = normalize(worldLightDir + viewDir);

//计算高光信息
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(worldNormal, halfDir)), _Gloss);

return fixed4(ambient + diffuse + specular, 1.0);