定向光
首先我们定义一个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);
}