OpenGL基礎18:光照基礎

 

真實的光照非常的複雜,所以有關光照的算法和論文也有不少,想要模擬出更真實的光照往往需要很強的實力,很牛的算法以及很高的數學/物理水平,與此相關的技術到現在爲止也只是在發展中(包括目前比較火的“光線追蹤”),當然,還是要從最簡單的入手,儘可能以最低的門檻,做出個大致的樣子來

一、光照模型與光源

之所以說光照比較複雜,主要是在物理和數學專業上的難度,光通常都不是來自於同一光源,而是來自散落於我們周圍的很多光源,即使它們可能並不是那麼顯而易見,光的一個屬性是,它可以向很多方向發散和反彈,又或是多次反射,所以光最後到達的地點可能並不是它所臨近的直射方向;

光能夠像這樣反射(Reflect)到其他表面,一個物體的光照可能受到來自一個非直射的光源影響

一種基礎光照模型:馮氏光照模型(Phong)的主要結構由3個元素組成

  • 環境(Ambient)光:即使在黑暗的情況下,世界上也仍然有一些光亮(月亮、一個來自遠處的光),所以物體永遠不會是完全黑暗的,只要你在室外
  • 漫反射(Diffuse):模擬一個發光物對物體的方向性影響(Directional Impact),它是馮氏光照模型最顯著的組成部分,面向光源的一面比其他面會更亮
  • 鏡面(Specular)光照:模擬有光澤物體上面出現的亮點,鏡面光照的顏色相比於物體的顏色更傾向於光的顏色

幾種常見光源:

  • 環境光:一種低強度的光,沒有位置的概念,由光線經過周圍環境表面多次反射後形成的,可以用環境光可以描述一塊區域的亮度,通常是常量(對應光照模型中的環境光)
  • 太陽光:定向光源,在無窮遠出發射光線,光線是平行的,強度不會隨着距離衰減(一般場景中只有至多一個)
  • 點光源:在有限空間內某個點上發出的光線,光線強度會隨着距離衰減(最常見光源)
  • 聚光燈(SpotLight):一種具有錐形效果的光源,該光源擁有產生光的方向和角度,有主照射方向,光線強度會隨着距離,延着中心向外衰減(例如手電筒,舞臺燈)

陰影(Shadow)

  • 軟陰影:陰影邊界柔和,漸變,沒有鋸齒,常見而又普通
  • 硬陰影:邊界銳利,通常出現在在和物體的交替處或者是光打下來離物體比較近的地方

 

二、環境光照

考慮環境光的性質,實現環境光照出乎意料的簡單,如下修改物體的片段着色器:我們只需要用光的顏色乘以一個很小的常量環境因子,再乘以物體的顏色就ok了,這也是最基礎的算法

#version 330 core
out vec4 color;
uniform vec3 objectColor;
uniform vec3 lightColor;
in vec2 texIn;
uniform sampler2D texOutA;
void main()
{
    float ambientStrength = 0.1f;
    vec3 ambient = ambientStrength * lightColor;
    vec3 result = ambient * objectColor;
    color = vec4(result, 1.0f);
}

爲了能看出效果,把背景換成黑色:

如果你覺得這過於簡單,可以去嘗試學習全局照明(Global Illumination)算法

 

三、漫反射和鏡面反射

再回到初高中物理,漫反射和鏡面反射的區別可以用一張圖表示:

爲了簡化問題,我們當然不可能去嘗試計算每條光線的反射角和反射結果,我們只需要知道:漫反射是一個“混沌”的過程,也就是說,無論在什麼方向上觀察物體,從物體反射到我們眼中的光線強度和方向(總量)都是大致相似的,我們只需要考慮光與物體之間的關係,而對於鏡面反射,我們就需要考慮到我們的觀察視角,換句話說:

  • 對於漫反射:我們簡單考慮入射光與物體表面法向量的夾角,夾角越大則越亮
  • 對於鏡面反射:我們簡單考慮反射光與視線方向的夾角,夾角越大則越亮

入射光和反射光關於物體反射點法向量對稱

對於實現可以參考後面的文章

 

參考文獻:https://learnopengl.com/Lighting/Basic-Lighting

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章