OpenGL中的光照系列之一 基本理論

2021-06-26 19:05:18 字數 2025 閱讀 2659

神說、要有光、就有了光   —— 聖經

opengl中的光照、材質和顏色總是緊密聯絡在一起的,光作為opengl中的乙個基本特性,在模擬真實環境中有著不可替代的作用。本系列討論顏色與光照的基本原理、opengl中光照的模擬方式、各種引數的設定以及使用等,通過這些內容,讓讀者對整個opengl的光照體系有乙個完整的認識。

儘管當前opengl的程式設計從舊式的固定管線模式(glbegin、glvertex、glend)過渡到了當今的可程式設計管線模式(shader),但是本文中描述的內容依然適用。

顏色只是某種波長的光,能夠被肉眼看到。在高中物理中我們知道光分為很多態別,包括可見光、紅外線、紫外線、x射線等,我們眼睛可以接受的只是其中某個波段的光,下圖是可見光的波普範圍:

當乙個物體我們說它是紅色時,實際上它並不是紅色,它只是反射紅色的光(而吸收了其他顏色的光),這樣我們眼睛接受到的都是紅色的光,讓我們覺得它是紅色的。如果我們使用綠色的光去照射它,那麼我們實際上什麼也看不到(因為綠色的光都被物體吸收了),許多魔術師都用這種方式來「欺騙」我們的眼睛。

眼睛有三種型別的錐細胞,它們都會對光子做出反映,每種型別的錐細胞對特定波長的光子敏感,其中一種對紅色敏感、一種對綠敏感、另一種對藍色敏感,這些不同的錐細胞被指定波長的光子刺激到之後,大腦會接受到訊號,讓人眼感受到物體的顏色。

現實生活中的光是難以描述的,opengl使用了一種簡單的方式實現對光的模擬,它將光分為三種成分:環境光(ambient)、散射光(diffuse)、和鏡面光(specular),這只是一種模擬方式,讀者也可以使用自己的方式來模擬光照,這種方式的模擬稱為ads光照模型。下面我們對這些光的成分逐一分析:

環境光並不是來自特定的方向,它來自某個光源,但卻在房間或者場景中四處反射,沒有方向可言,有環境光所照射的物體在所有方向的表面都是均勻照亮的,因此看起來像乙個2d的物體,下圖是某個球體僅在環境光照射下的效果:

散射光具有方向性,來自於乙個特定的方向,根據入射光線的角度在表面上均勻的反射開來。被散射光照射的表面看起來更亮一些,下圖是乙個球體受到紅色的散射光照射之後的效果(光線從左向右)

鏡面高光也具有方向性,它的光線來自同乙個方向,與散射光不同的是,入射之後的光線會沿乙個特定的方向反射。高強度的鏡面光趨向於在它表面形成乙個亮點,由於它的高度方向性,鏡面光甚至可能看不到,下圖是乙個受鏡面光照射的球體的效果:

沒有一種光源是純粹由上面所述的任何一種型別的光所組成的。事實上光源是由各種強度的不同型別的光所組成的。例如實驗室的紅色雷射束幾乎是由純的紅色鏡面光組成的,當它照射到物體時會產生乙個非常強的亮點。但是煙或灰塵會導致雷射束發散,產生非常小的環境光成分。

有前面的論述我們知道,物體的顏色如何最終確定除了和光有關係之外,還和物體的材質有關。乙個物體的顏色是由它所反射的光的波長來定義的,乙個藍色的球反**絕大部分的藍色光子,並吸收了絕大部分的其他光子。一般來說現實世界中的絕大多數場景都是由均勻包含所有各種顏色光的白色光組成,絕大多數物體都呈現它們的「自然顏色」。總體來說就是:在開啟光照計算之後,物體的顏色最終是什麼需要依據光照和物體的材質共同決定。opengl的物體材質包括如下部分:

材質中的環境顏色會與光中的環境顏色計算是最終決定物體顏色的因素之一,具體的作用計算可以參考後續內容

會與光中的對應部分計算決定物體顏色的因素之一

同上也是參與最終決定物體顏色計算的乙個引數

可以讓物體看上去好像發光體,一般用來模擬場景中的光源效果

下文接著介紹opengl光照的計算

對於OpenGL中光照和顏色混合的理解

摘自 opengl遊戲程式設計 光照 光照變數 float ambientlight 環境光 float diffuselight float matdiff 第乙個變數matambient定義了材質表面對於光線中的環境光分量是如何反應的。此例中,變數中的每乙個值都為1.0,意味市場環境光的紅色 綠...

戰五渣系列之一(sql中的join)

1.為什麼第一篇文章就是sql呢,因為最近看到乙個文章2副圖秒懂sql中的join 最重要的是在我遇到的程式設計師中,不懂join和left join的區別的有很多,促使我不得不戰五渣 2.且看我如何戰五渣!什麼是left join?表 department,employee 需求 查詢部門5 de...

關於指標的強制轉化之一(基類有虛

include using namespace std class inondelegatingunknown class iunknown class a public iunknown,public inondelegatingunknown void a queryinte ce void p...