learnOpenGL 2.5 多光源
程序员文章站
2022-06-10 21:09:49
...
之前我们学习了多种光源,也介绍了他们的计算方法。
当画面中有多个光源时,为了方面管理和计算光照,我们将它们分别建立结构体和计算函数。
struct dirLight{
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float constant;
float linear;
float quadratic;
};
struct pointLight{
vec3 position;
vec3 ambient;
vec3 diffuse;
vec3 specular;
float constant;
float linear;
float quadratic;
};
struct spotLight{
vec3 ambient;
vec3 diffuse;
vec3 specular;
vec3 position;
vec3 direction;
float constant;
float linear;
float quadratic;
float cutoff;
float outcutoff;
};
计算函数以聚光光源为例
vec3 calcspotlight(spotLight spotlight,vec3 normal,vec3 viewdir,vec3 fragpos)
{
vec3 ambient=spotlight.ambient*texture(material.diffuse,texcoor).rgb;
vec3 lightdir=normalize(spotlight.position-fragpos);
float diff=max(dot(lightdir,normal),0);
vec3 diffuse=diff*spotlight.diffuse*texture(material.diffuse,texcoor).rgb;
vec3 reflectdir=normalize(reflect(-lightdir,normal));
float spec=pow(max(dot(reflectdir,viewdir),0),material.shininess);
vec3 specular=spotlight.specular*spec*texture(material.specular,texcoor).rgb;
float distance=length(spotlight.position-fragpos);
float attenuation=1.0/(spotlight.constant+spotlight.linear*distance+spotlight.quadratic*distance*distance);
ambient *= attenuation;
diffuse *= attenuation;
specular *= attenuation;
float theta=dot(normalize(-spotlight.direction),lightdir);
float epsilon=spotlight.cutoff-spotlight.outcutoff;
float intensity=clamp((theta-spotlight.outcutoff)/epsilon,0.0,1.0);
diffuse*=intensity;
specular*=intensity;
return (ambient+diffuse+specular);
}
这样一来我们在shader的主函数中就只要调用这些计算函数了,多光源的计算也会变得方便许多。
void main()
{
vec3 norm=normalize(normal);
vec3 viewdir=normalize(viewpos-fragpos);
vec3 result=calcdirlight(dirlight,norm,viewdir);
for(int i=0;i<4;i++)
result+=calcpointlight(pointlight[i],norm,viewdir,fragpos);
result+=calcspotlight(spotlight,norm,viewdir,fragpos);
FragColor=vec4(result,1.0f);
}
上一篇: python包 pyGAPS 可用于拟合吸附等温线
下一篇: js中判断对象是否为空