在學習過光照,材質,投光物之後,現在我們把這些效果結合起來。我們顯示這樣的效果:在陽光照射下,有幾個點光源,同時有一個聚光燈,此時在不同位置的物體被光照的效果。
要定義多個光源,那麼就需要定義不同的結構體,同時我們分開來不同的光照計算,使代碼更清晰,GLSL定義方法和C相似,不過需要先聲明,然後再定義,如下
void calc(); //聲明一個函數
void calc() //定義一個函數
{
//函數代碼
}
我們先定義定向光,結構體定義爲
// 定向光
struct DirLight {
vec3 direction;
vec3 ambient;
vec3 diffuse;
vec3 specular;
};
uniform DirLight dirLight;
再定義一個計算定向光照的方法calcDirLight,我們在main函數中調用calcDirLight即可得到結果,
……
vec3 calcDirLight(DirLight light, vec3 viewDir);
void main() {
vec3 viewDir = normalize(-fragPos);
// 計算定向光
vec3 result = calcDirLight(dirLight, viewDir);
gl_FragColor = vec4(result, 1.0);
}
// 計算光照
vec3 calcDirLight(DirLight light, vec3 viewDir) {
……
// 結果
return (ambient + diffuse + specular);
}
定向光的計算可以參考前面的章節,這裏不再贅述。
點光源的定義,我們這裏使用數組保存四個點光源的數據,計算時也是使用for循環分別計算,然後把結果相加
// 點光源
struct PointLight {
……
};
#define NR_POINT_LIGHTS 4
uniform PointLight pointLights[NR_POINT_LIGHTS];
……
vec3 calcPointLight(PointLight light, vec3 viewDir);
void main() {
vec3 viewDir = normalize(-fragPos);
// 計算定向光
vec3 result = calcDirLight(dirLight, viewDir);
// 計算點光源
for (int i = 0; i < NR_POINT_LIGHTS; i++){
result += calcPointLight(pointLights[i], viewDir);
}
gl_FragColor = vec4(result, 1.0);
}
// 計算點光源
vec3 calcPointLight(PointLight light, vec3 viewDir){
……
// 結果
return (ambient + diffuse + specular);
}
需要注意的是,在傳入點光源的數據時,傳入的參數名需要以:pointLights[索引] 開頭。
最後是聚光的效果,
//聚光燈
struct SpotLight {
……
};
uniform SpotLight spotLight;
……
vec3 calcSpotLight(SpotLight light, vec3 viewDir);
void main() {
vec3 viewDir = normalize(-fragPos);
// 計算定向光
vec3 result = calcDirLight(dirLight, viewDir);
// 計算點光源
for (int i = 0; i < NR_POINT_LIGHTS; i++){
result += calcPointLight(pointLights[i], viewDir);
}
// 計算聚光
result += calcSpotLight(spotLight, viewDir);
gl_FragColor = vec4(result, 1.0);
}
……
// 計算聚光
vec3 calcSpotLight(SpotLight light, vec3 viewDir){
……
// 結果
return (ambient + diffuse + specular);
}
最後傳入我們定義的物體和光數據即可,效果圖如下
本章對應文檔https://learnopengl-cn.github.io/02%20Lighting/06%20Multiple%20lights/,源碼地址https://github.com/jklwan/OpenGLProject/blob/master/sample/src/main/java/com/chends/opengl/renderer/light/LightCastersSpotLightRenderer.java
關於簡單光照的學習到這裏就結束了,後面會開始學習模型加載的部分。