OpenGL学习之路之光源大总结

OpenGL学习之路之光源大总结

十二月 19, 2021

光源所需条件

1.光照信息

定向光 点光源 聚光灯的属性

2.法线向量

将顶点着色器的法线信息接收,并进行标准化

1
vec3 uNormal=normalize(Normal);

3.片元到摄像头的位置

1
vec3 dirToCamera=normalize(cameraPos-FragPos);

定向光

主要光照信息

1
2
3
4
5
struct LightDirectional{
vec3 pos;//光源坐标
vec3 color;//光颜色
vec3 dirToLight;//光照角度
};

特点

不需要光照衰弱,光照与位置无关

diffuse

1
2
diffuseIntersity=max(dot(light.dirToLight,Normal),0);
diffuse=diffuseIntersity*light.color*texture(material.diffuse,TexCoord).rgb;

specular

1
2
specularIntersity=pow(max(dot(normalize(reflect(-light.dirToLight,Normal)),dirToCamera),0),material.shininess);
vec3 specular=specularIntersity*light.color*texture(material.specular,TexCoord).rgb;

点光源

主要光照信息

1
2
3
4
5
6
7
8
struct LightPoint{
vec3 pos;
vec3 color;
vec3 dirToLight;//用不上
float constant;//1.0f
float linear;//0.09f
float quadratic;//0.032f
};

特点

与光照方向无关

attenuation

1
2
float distantes=length(light.pos-FragPos);
float attenuation=1.0f/light.constant+light.linear*distantes+light.quadratic*distantes*distantes;

diffuse

1
2
diffuseInyersity=max(dot(normalize(light.pos-FragPos),Normal),0);
vec3 diffuse=diffuseIntensity*texture(material.diffuse,TexCoord).rgb*light.color;

specular

1
2
float specularIntersity=pow(max(dot(normalize(reflect(-normalize(light.pos-FragPos),uNormal)),dirToCamera),0),material.shininess);
vec3 specular=specularIntersity*light.color*texture(material.specular,TexCoord).rgb;

聚光灯

主要光照信息

1
2
3
4
5
6
7
8
9
10
struct LightSpot{
vec3 pos;
vec3 color;
vec3 dirToLight;//有用
float constant;
float linear;
float quadratic;
float cosPhyInner;
float cosPhyOutter;
};

特点

边缘模糊化,对比点光源需要会受角度影响

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
vec3 result=vec3(0,0,0);
//attenuation
float distances= length(light.pos - FragPos);
float attenuation=1.0f/(light.constant+light.linear*distances+light.quadratic*distances*distances);
float spotRatio=0;
float cosTheta=dot(normalize(FragPos-light.pos),-1.0f*light.dirToLight);
//cosTheta=1;
if(cosTheta > light.cosPhyInner)
{
spotRatio=1.0f;
}else if(cosTheta > light.cosPhyOutter){
//spotRatio=1.0f-(cosTheta-light.cosPhyInner)/(light.cosPhyOutter-light.cosPhyInner);
spotRatio=(light.cosPhyOutter-cosTheta)/(light.cosPhyOutter - light.cosPhyInner);
}
else{
spotRatio=0.0f;
}
attenuation*=spotRatio;
//diffuse
float diffuseIntensity=max(dot(normalize(light.pos-FragPos),uNormal),0);
vec3 diffuse=texture(material.diffuse,TexCoord).rgb*light.color*diffuseIntensity;
result+=diffuse;

//specular
float specularIntersity=pow(max(dot(normalize(reflect(-normalize(light.pos-FragPos),uNormal)),dirToCamera),0),material.shininess);
vec3 specular = specularIntersity*texture(material.specular,TexCoord).rgb*light.color;
result+=specular;
//result*=attenuation;
result*=spotRatio;
return result;