學習OpenGL ES for Android(十四)— 多光源

在學習過光照,材質,投光物之後,現在我們把這些效果結合起來。我們顯示這樣的效果:在陽光照射下,有幾個點光源,同時有一個聚光燈,此時在不同位置的物體被光照的效果。

要定義多個光源,那麼就需要定義不同的結構體,同時我們分開來不同的光照計算,使代碼更清晰,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

關於簡單光照的學習到這裏就結束了,後面會開始學習模型加載的部分。

發佈了52 篇原創文章 · 獲贊 17 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章