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

OpenGL光线六 opengl多光源 MultipleLights

程序员文章站 2022-06-10 21:14:13
...

一、定义短多个光源
//平行光
LightDirectional lightD(glm::vec3(10.0f, 10.0f, -5.0f), glm::vec3(glm::radians(90.0f), glm::radians(0.0f), 0));
//点光源
LightPoint lightP0(glm::vec3(1.0f, .0f, .0f), glm::vec3(glm::radians(45.0f), glm::radians(45.0f), 0), glm::vec3(1.0f, 0.0f, 0.0f));
LightPoint lightP1(glm::vec3(.0f, 1.0f, .0f), glm::vec3(glm::radians(45.0f), glm::radians(45.0f), 0), glm::vec3(0.0f, 1.0f, 0.0f));
LightPoint lightP2(glm::vec3(.0f, .0f, 1.0f), glm::vec3(glm::radians(45.0f), glm::radians(45.0f), 0), glm::vec3(0.0f, 0.0f, 10.0f));
LightPoint lightP3(glm::vec3(1.0f, 3.0f, -.0f), glm::vec3(glm::radians(45.0f), glm::radians(45.0f), 0), glm::vec3(1.0f, 1.0f, 1.0f));
//聚光灯
LightSpot lightS(glm::vec3(0.0f, 5.0f, 0.0f), glm::vec3(glm::radians(90.0f), 0, 0), glm::vec3(1.0f, 1.0f, 1.0f));

二、通过uniform传递光源信息
//平行光
glUniform3f(glGetUniformLocation(pshader->ID, “lightD.color”), lightD.color.r, lightD.color.g, lightD.color.b);
glUniform3f(glGetUniformLocation(pshader->ID, “lightD.dirToLight”), lightD.direction.x, lightD.direction.y, lightD.direction.z);
//点光源0
glUniform3f(glGetUniformLocation(pshader->ID, “lightP[0].pos”), lightP0.postion.x, lightP0.postion.y, lightP0.postion.z);
glUniform3f(glGetUniformLocation(pshader->ID, “lightP[0].color”), lightP0.color.r, lightP0.color.g, lightP0.color.b);
glUniform1f(glGetUniformLocation(pshader->ID, “lightP[0].constant”), lightP0.constant);
glUniform1f(glGetUniformLocation(pshader->ID, “lightP[0].linear”), lightP0.linear);
glUniform1f(glGetUniformLocation(pshader->ID, “lightP[0].quadratic”), lightP0.quadratic);
//点光源1
glUniform3f(glGetUniformLocation(pshader->ID, “lightP[1].pos”), lightP1.postion.x, lightP1.postion.y, lightP1.postion.z);
glUniform3f(glGetUniformLocation(pshader->ID, “lightP[1].color”), lightP1.color.r, lightP1.color.g, lightP1.color.b);
glUniform1f(glGetUniformLocation(pshader->ID, “lightP[1].constant”), lightP1.constant);
glUniform1f(glGetUniformLocation(pshader->ID, “lightP[1].linear”), lightP1.linear);
glUniform1f(glGetUniformLocation(pshader->ID, “lightP[1].quadratic”), lightP1.quadratic);
//点光源2
glUniform3f(glGetUniformLocation(pshader->ID, “lightP[2].pos”), lightP2.postion.x, lightP2.postion.y, lightP2.postion.z);
glUniform3f(glGetUniformLocation(pshader->ID, “lightP[2].color”), lightP2.color.r, lightP2.color.g, lightP2.color.b);
glUniform1f(glGetUniformLocation(pshader->ID, “lightP[2].constant”), lightP2.constant);
glUniform1f(glGetUniformLocation(pshader->ID, “lightP[2].linear”), lightP2.linear);
glUniform1f(glGetUniformLocation(pshader->ID, “lightP[2].quadratic”), lightP2.quadratic);
//点光源3
glUniform3f(glGetUniformLocation(pshader->ID, “lightP[3].pos”), lightP3.postion.x, lightP3.postion.y, lightP3.postion.z);
glUniform3f(glGetUniformLocation(pshader->ID, “lightP[3].color”), lightP3.color.r, lightP3.color.g, lightP3.color.b);
glUniform1f(glGetUniformLocation(pshader->ID, “lightP[3].constant”), lightP3.constant);
glUniform1f(glGetUniformLocation(pshader->ID, “lightP[3].linear”), lightP3.linear);
glUniform1f(glGetUniformLocation(pshader->ID, “lightP[3].quadratic”), lightP3.quadratic);
//聚光灯
glUniform3f(glGetUniformLocation(pshader->ID, “lightS.pos”), lightS.postion.x, lightS.postion.y, lightS.postion.z);
glUniform3f(glGetUniformLocation(pshader->ID, “lightS.color”), lightS.color.r, lightS.color.g, lightS.color.b);
glUniform3f(glGetUniformLocation(pshader->ID, “lightS.dirToLight”), lightS.direction.x, lightS.direction.y, lightS.direction.z);
glUniform1f(glGetUniformLocation(pshader->ID, “lightS.constant”), lightS.constant);
glUniform1f(glGetUniformLocation(pshader->ID, “lightS.linear”), lightS.linear);
glUniform1f(glGetUniformLocation(pshader->ID, “lightS.quadratic”), lightS.quadratic);
glUniform1f(glGetUniformLocation(pshader->ID, “lightS.cosPhyInner”), lightS.cosPhyInner);
glUniform1f(glGetUniformLocation(pshader->ID, “lightS.cosPhyOutter”), lightS.cosPhyOutter);

三、在fragmentShader中计算不同光源,并求和
1、光照模型
//////////////光照模型//////////////////////
vec3 lightingMode(Material material,vec3 lightColor,vec3 lightDir,vec3 uNormal,vec3 dirToCamera, bool glow){
vec3 resultColor;
//specular
vec3 reflectVec =reflect(lightDir,uNormal);
float specularAmount = pow(max(dot(reflectVec,dirToCamera),0.0f),material.shininess);
vec3 specular = texture(material.specular,TextCoord).rgbspecularAmountlightColor;

//deffuse
float diffuseAmount = max(dot(lightDir,uNormal),0.0f);
vec3 diffuse = texture(material.diffuse,TextCoord).rgb* diffuseAmount*lightColor;

//ambient
vec3 ambient = texture(material.diffuse,TextCoord).rgb*ambientColor;
ambient = ambient/2+ambient*(specularAmount+diffuseAmount);
//vec3 ambient = texture(material.diffuse,TextCoord).rgb*ambientColor*(specularAmount+diffuseAmount);

//emission
vec3 emission=vec3(0,0,0);
if(glow){
	emission = texture(material.emission,TextCoord).rgb;
}
return resultColor = ambient+diffuse+specular+emission;

}
2、计算三种不同的光源
//计算平行光
vec3 CalcLightDirectional(LightDirectional light,vec3 uNormal,vec3 dirToCamera){
return lightingMode(material,light.color,light.dirToLight,uNormal,dirToCamera,false);
}
//计算点光源
vec3 CalcLightPoint(LightPoint light,vec3 uNormal,vec3 dirToCamera){
vec3 resultColor=vec3(0,0,0);
//attenuation衰减系数
float dist = length(light.pos-FragPos);
float attenuation = 1/(light.constant+light.lineardist+light.quadraticdistdist);
resultColor = light.color
attenuation;
vec3 lightDir = normalize(light.pos-FragPos);
return lightingMode(material,resultColor,lightDir,uNormal,dirToCamera,false);
}
//计算聚光灯
vec3 CalcLightSpot(LightSpot light,vec3 uNormal,vec3 dirToCamera){
vec3 resultColor=vec3(0,0,0);
//attenuation衰减系数
float dist = length(light.pos-FragPos);
float attenuation = 1/(light.constant+light.lineardist+light.quadraticdist*dist);

float cosTheta = dot(normalize(FragPos - light.pos),-1*light.dirToLight);
float spotRatio = (cosTheta-light.cosPhyOutter)/(light.cosPhyInner-light.cosPhyOutter);
if(cosTheta>light.cosPhyInner){
	//inside
	resultColor = light.color*attenuation;
}else if(cosTheta>light.cosPhyOutter){
	//middle
	resultColor = light.color*spotRatio*attenuation;
}else{
	//outside
	resultColor = light.color*0.0f;
}
vec3 lightDir = normalize(light.pos-FragPos);
return lightingMode(material,resultColor,lightDir,uNormal,dirToCamera,false);

}
3、将计算的结果叠加
vec3 finalColor=vec3(0,0,0);
//1、LightDirection 平行光
vec3 uNormal=normalize(Normal);
vec3 dirToCamera=normalize(cameraPos-FragPos);
finalColor += CalcLightDirectional(lightD,uNormal,dirToCamera);
//2、LightPoint 点光源
for(int i=0;i<4;i++){
finalColor += CalcLightPoint(lightP[i],uNormal,dirToCamera);
}
//3、LightSpot 聚光灯
finalColor += CalcLightSpot(lightS,uNormal,dirToCamera);

FragColor = vec4(finalColor,1.0f);

代码Git地址.

相关标签: opengl