Phong模型由三种反射光组成,分别是环境光、漫反射光、镜面反射光。
简单来说就是不可能黑暗的很纯粹,在减少资源开销的情况下,我们使用一个简单的很小的常量环境因子乘以光照颜色。
void main()
{
float ambientStrength = 0.1;
vec3 ambient = ambientStrength * lightColor;
vec3 result = ambient * objectColor;
FragColor = vec4(result, 1.0);
}
简而言之就是,物体表面不同的点,反射的光强并不一定是一样的。在Phong模型里,光线的入射角和该点的法线越近光强越强。
vec3 norm = normalize(Normal);
vec3 lightDir = normalize(light.position - FragPos);
float diff = max(dot(norm, lightDir), 0.0);
vec3 diffuse = diff * lightColor;
同上,反射后的光强随着观察者的观察角度而变化
观察者的观察角度和反射向量越近则光强越强
vec3 viewDir = normalize(viewPos - FragPos);
vec3 reflectDir = reflect(-lightDir, norm);
float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess);
vec3 specular = light.specular * (spec * material.specular);
长话短说,就是物体的自身属性会对光产生不同的反应。
主要开始在shader用结构体存储数据
我们可以不要把贴图当做一张图,而是一种数据存储方式
简而言之就是贴图存储了上述的漫反射参数,在片元着色器里对其进行采样赋值。
vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoords));
vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoords));
vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoords));
FragColor = vec4(ambient + diffuse + specular, 1.0);
用Unity表示效果
其实就是光源
vec3 lightDir = normalize(-light.direction);
定义一个光线方向向量而不是位置向量来模拟一个定向光
球形加光强衰减
float distance = length(light.position - FragPos);
float attenuation = 1.0 / (light.constant + light.linear * distance +
light.quadratic * (distance * distance));
类似锥形,手电。
void main()
{
// 属性
vec3 norm = normalize(Normal);
vec3 viewDir = normalize(viewPos - FragPos);
// 第一阶段:定向光照
vec3 result = CalcDirLight(dirLight, norm, viewDir);
// 第二阶段:点光源
for(int i = 0; i < NR_POINT_LIGHTS; i++)
result += CalcPointLight(pointLights[i], norm, FragPos, viewDir);
// 第三阶段:聚光
result += CalcSpotLight(spotLight, norm, FragPos, viewDir);
FragColor = vec4(result, 1.0);
}
其实就是分装不同的类型,然后逐一叠加。
但是此处并未考虑前向或者延迟渲染。