欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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);
}
相关标签: 笔记 opengl