前言:
ADS光照模型:
ADS模型是一种光照模型,由环境光照(Ambient)、漫反射光照(Diffuse)和镜面光照(Specular)三个部分组成。
它在计算表面的颜色和明暗度时分别考虑了这三种光照的影响。
Phong 光照模型:
它由环境光照、漫反射光照和镜面光照组成,与ADS模型的三个部分相同。
然而,Phong光照模型还包括了一个镜面反射指数(Specular Exponent)的参数,用于调整镜面高光的大小和锐利度。
可以说,ADS模型是Phong光照模型的一个特例,当Phong光照模型中的镜面反射指数为1时,就等同于ADS模型。
也就是说,ADS模型可以看作是Phong光照模型中镜面反射指数为1时的简化形式。
镜面反射指数:
镜面反射指数(Specular Exponent)用于调整镜面光照效果的大小和锐利度。它是一个控制镜面高光反射散射程度的参数。
具体来说,镜面反射指数影响了光照模型中的镜面光照计算,其中包括Phong光照模型和Blinn-Phong光照模型。
较小的镜面反射指数会产生较宽的散射高光,使高光区域的亮度扩散到周围较大的区域。
而较大的镜面反射指数会产生较窄的散射高光,使高光区域的亮度集中在一个较小的区域。
通过调整镜面反射指数的值,可以达到不同的效果。
较小的值可以用于模拟光滑表面(如金属)上的小而锐利的高光,
而较大的值适用于模拟粗糙表面(如皮肤或木材)上的宽散的高光。
环境光照(Ambient)、漫反射光照(Diffuse)和镜面光照(Specular):
环境光照:
表示物体表面受到周围环境光线的照射。环境光照的颜色通常是固定值,与物体的材质和位置无关
漫反射光照:
diffuse = Kd * L * max(dot(N, L), 0)
其中,Kd 是物体表面材质的漫反射系数,L 是入射光线的漫反射系数,N 是物体表面的法向量,L 和 N 的点积表示光线和法向量之间的夹角,max(dot(N, L), 0) 的值保证该夹角在 0 到 90 度之间。
镜面反射光照:
specular = Ks * L * pow(max(dot(R, V), 0), shininess)
其中,Ks 是物体表面材质的镜面反射系数,L 是入射光线的强度,R 是光线在物体表面反射的方向,V 是视线方向,R 和 V 的点积表示反射光线和视线方向之间的夹角,pow(max(dot(R, V), 0), shininess) 的值表示反射光线
代码展示:
这块主要是在着色器中实现, 真正代码并没有太多:
顶点着色器:
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
out vec3 FragPos;
out vec3 Normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
void main()
{
FragPos = vec3(model * vec4(aPos, 1.0));
Normal = mat3(transpose(inverse(model))) * aNormal;
gl_Position = projection * view * vec4(FragPos, 1.0);
}
片段着色器:
#version 330 core
out vec4 FragColor;
in vec3 Normal;
in vec3 FragPos;
struct Material {
vec3 ambient;
vec3 diffuse;
vec3 specular;
float shininess;
};
struct Light {
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform vec3 viewPos;
uniform Material material;
uniform Light light;
void main()
{
// ambient
vec3 ambient = material.ambient * light.ambient;
// diffuse
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(light.position - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = (diff * material.diffuse) * light.diffuse;
// specular
float specularStrength = 0.5;
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 specular = (material.specular * spec) * light.specular;
vec3 result = (ambient + diffuse + specular);
FragColor = vec4(result, 1.0);
}