OpenGL学习之多光源

定向光

首先我们定义一个LightDirection结构体和一个uniform变量

struct LightDirection{
vec3 pos;
vec3 color;
vec3 dirToLight;
};
uniform  LightDirection lightD;

接下来我们将LightDirection传入CalcLightDirection函数

vec3 CalcLightDirection(LightDirection light,vec3 uNormal,vec3 dirToCamera)
{
	//diffuse  pow(max(dot(L,N),0),shininess)
	float diffIntensity=max(dot(light.dirToLight,uNormal),0);
	vec3 diffColor = diffIntensity*light.color*texture(material.specular,TexCoord).rgb;
	
	//specular  pow(max(dot(R,Cam),0),shininess)
	vec3 R = normalize(reflect(-light.dirToLight,uNormal));
	float specIntensity = pow( max(dot(R , dirToCamera),0),material.shininess);
	vec3 specColor = specIntensity * light.color*texture(material.diffuse,TexCoord).rgb;
	
	vec3 result = diffColor*specColor;
	return result;
}

在main中

LightDirection lightD = LightDirection(glm::vec3(1.0f, 1.0f, -1.0f),
	glm::vec3(glm::radians(45.0f), glm::radians(45.0f), 0),
	glm::vec3(1.0f, 1.0f, 1.0f));


/*...
...
...
*/
glUniform3f(glGetUniformLocation(ourShader->ID, "lightD.pos"), lightD.position.x, lightD.position.y, lightD.position.z);	//light position
glUniform3f(glGetUniformLocation(ourShader->ID, "lightD.dirToLight"), lightD.color.x, lightD.color.y, lightD.color.z);	//light color
glUniform3f(glGetUniformLocation(ourShader->ID, "lightD.color"), lightD.direction.x, lightD.direction.y, lightD.direction.z);


点光源

struct LightPoint{
vec3 pos;
vec3 color;
vec3 dirToLight;
float constant;
float linear;
float quadratic;
};
uniform LightPoint lightP0;
uniform LightPoint lightP1;
uniform LightPoint lightP2;
uniform LightPoint lightP3;
vec3 CalclightPoint(LightPoint light,vec3 uNormal,vec3 dirToCamera)
{
	//attenuation
	float dist=length(light.pos-FragPos);
	float attenuation = 1/(light.constant + light.linear * dist + 
                light.quadratic * (dist * dist));

	//diffuse
	float diffIntensity=max(dot(normalize(light.pos-FragPos),uNormal),0)*attenuation;
	vec3 diffColor=diffIntensity*light.color*texture(material.diffuse,TexCoord).rgb;

	//specular
	vec3 R = normalize(reflect(-normalize(light.pos-FragPos),uNormal));
	float specIntensity = pow( max(dot(R , dirToCamera),0),material.shininess)*attenuation;
	vec3 specColor = specIntensity * light.color*texture(material.diffuse,TexCoord).rgb;

	vec3  result=diffColor+specColor;
	return result;
	
}
LightPoint lightP0 = LightPoint(glm::vec3(1.0f, 1.0f, -1.0f),
	glm::vec3(glm::radians(45.0f), glm::radians(45.0f), 0),
	glm::vec3(1.0f, 1.0f, 1.0f));

LightPoint lightP1 = LightPoint(glm::vec3(1.0f, 0, 0),
	glm::vec3(glm::radians(45.0f), glm::radians(45.0f), 0),
	glm::vec3(1.0f, 0, 0));

LightPoint lightP2 = LightPoint(glm::vec3(0, 1.0f,0),
	glm::vec3(glm::radians(45.0f), glm::radians(45.0f), 0),
	glm::vec3(0, 1.0f, 0));

LightPoint lightP3= LightPoint(glm::vec3(0, 0, 1.0f),
	glm::vec3(glm::radians(45.0f), glm::radians(45.0f), 0),
	glm::vec3(0, 0, 1.0f));

/*
...
...*/
glUniform3f(glGetUniformLocation(ourShader->ID, "lightP0.pos"), lightP0.position.x, lightP0.position.y, lightP0.position.z);	//light position
glUniform3f(glGetUniformLocation(ourShader->ID, "lightP0.dirToLight"), lightP0.color.x, lightP0.color.y, lightP0.color.z);	//light color
glUniform3f(glGetUniformLocation(ourShader->ID, "lightP0.color"), lightP0.direction.x, lightP0.direction.y, lightP0.direction.z);
glUniform1f(glGetUniformLocation(ourShader->ID, "lightP0.constant"), lightP0.constant);
glUniform1f(glGetUniformLocation(ourShader->ID, "lightP0.liner"), lightP0.linear);
glUniform1f(glGetUniformLocation(ourShader->ID, "lightP0.quadratic"), lightP0.quadratic);

glUniform3f(glGetUniformLocation(ourShader->ID, "lightP1.pos"), lightP1.position.x, lightP1.position.y, lightP1.position.z);	//light position
glUniform3f(glGetUniformLocation(ourShader->ID, "lightP1.dirToLight"), lightP1.color.x, lightP1.color.y, lightP1.color.z);	//light color
glUniform3f(glGetUniformLocation(ourShader->ID, "lightP1.color"), lightP1.direction.x, lightP1.direction.y, lightP1.direction.z);
glUniform1f(glGetUniformLocation(ourShader->ID, "lightP1.constant"), lightP1.constant);
glUniform1f(glGetUniformLocation(ourShader->ID, "lightP1.liner"), lightP1.linear);
glUniform1f(glGetUniformLocation(ourShader->ID, "lightP1.quadratic"), lightP1.quadratic);
			
glUniform3f(glGetUniformLocation(ourShader->ID, "lightP2.pos"), lightP2.position.x, lightP2.position.y, lightP2.position.z);	//light position
glUniform3f(glGetUniformLocation(ourShader->ID, "lightP2.dirToLight"), lightP2.color.x, lightP2.color.y, lightP2.color.z);	//light color
glUniform3f(glGetUniformLocation(ourShader->ID, "lightP2.color"), lightP2.direction.x, lightP2.direction.y, lightP2.direction.z);
glUniform1f(glGetUniformLocation(ourShader->ID, "lightP2.constant"), lightP2.constant);
glUniform1f(glGetUniformLocation(ourShader->ID, "lightP2.liner"), lightP2.linear);
glUniform1f(glGetUniformLocation(ourShader->ID, "lightP2.quadratic"), lightP2.quadratic);

glUniform3f(glGetUniformLocation(ourShader->ID, "lightP3.pos"), lightP3.position.x, lightP3.position.y, lightP3.position.z);	//light position
glUniform3f(glGetUniformLocation(ourShader->ID, "lightP3.dirToLight"), lightP3.color.x, lightP3.color.y, lightP3.color.z);	//light color
glUniform3f(glGetUniformLocation(ourShader->ID, "lightP3.color"), lightP3.direction.x, lightP3.direction.y, lightP3.direction.z);
glUniform1f(glGetUniformLocation(ourShader->ID, "lightP3.constant"), lightP3.constant);
glUniform1f(glGetUniformLocation(ourShader->ID, "lightP3.liner"), lightP3.linear);
glUniform1f(glGetUniformLocation(ourShader->ID, "lightP3.quadratic"), lightP3.quadratic);

聚光灯

struct LightSpot
{
vec3 pos;
vec3 color;
vec3 dirToLight;
float constant;
float linear;
float quadratic;
float cosPhyInner;
float cosPhyOutter;
};
uniform LightSpot lightS;

vec3 CalclightSpont(LightSpot light,vec3 uNormal,vec3 dirToCamera)
{
//attenuation
	float dist=length(light.pos-FragPos);
	float attenuation = 1/(light.constant + light.linear * dist + 
                light.quadratic * (dist * dist));

	float spotRation;
	float cosTheta=dot(normalize(FragPos-light.pos),-1*light.dirToLight);
		if(cosTheta>lightS.cosPhyInner)
	{
	//inside
	spotRation=1.0f;
	}
	else if(cosTheta>light.cosPhyOutter){
	//middle
	spotRation = 1.0-(cosTheta-light.cosPhyOutter)/(light.cosPhyOutter-light.cosPhyInner);
	}
	else{
	//outside
	spotRation=0;
	}
//FragColor = vec4((diffuse + (ambient + specular)*spotRation) * objColor,1.0);

	//diffuse
	float diffIntensity=max(dot(normalize(light.pos-FragPos),uNormal),0)*attenuation*spotRation;
	vec3 diffColor=diffIntensity*light.color*texture(material.diffuse,TexCoord).rgb;

	//specular
	vec3 R = normalize(reflect(-normalize(light.pos-FragPos),uNormal));
	float specIntensity = pow( max(dot(R , dirToCamera),0),material.shininess)*attenuation;
	vec3 specColor = specIntensity * light.color*texture(material.diffuse,TexCoord).rgb;

	vec3  result=diffColor+specColor;
return  result;
}

合并结果

我们已经定义了一个计算定向光的函数,一个计算点光源的函数和一个计算聚光灯的函数,将它们合并到一个main函数中

void main()
{

	vec3 finalResult=vec3(0,0,0);
	vec3 uNormal=normalize(Normal);
	vec3 dirToCamera=normalize(CameraPos-FragPos);

	 finalResult += CalcLightDirection(lightD,uNormal,dirToCamera);
	 finalResult +=CalclightPoint(lightP0,uNormal,dirToCamera);
	 finalResult +=CalclightPoint(lightP1,uNormal,dirToCamera);
	 finalResult +=CalclightPoint(lightP2,uNormal,dirToCamera);
	 finalResult +=CalclightPoint(lightP3,uNormal,dirToCamera);
	finalResult +=CalclightSpont(lightS,uNormal,dirToCamera);
	FragColor=vec4(finalResult,1.0);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Estelle_Z

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值