在3D場景中,每個像素最終顯示出來的顏色都是經過大量計算而得到的,其中一些計算是依賴於場景中的光照以及場景中物體對光線的反射和吸收情況.
例如,對於一個紅色的物體, 在白色光(白光是紅光,綠光和藍光等量的光) 的照射下它是紅色的, 而在綠色光的照射下它將顯示為黑色.
如果場景不存在光源效果,那么就沒有了3D效果。 下圖左邊是有光照的效果, 右圖是沒有光照的效果.
(一)OpenGL的光照模型
OpenGL的光, 可以分解為紅,綠,藍3種分量. 對於光源來說, 使用其發射的紅,綠,藍光的量來描述.
對於物體表面的材質則可以使用其在各個方向反射的紅,綠,藍光的比例來描述.
OpenGL的光照模型將光照分為4個獨立的部分:
環境光(ambient light)
漫射光(diffuse light)
鏡面反射光(specular light)
發射光(emitted light)
這4種光分別計算,然后被疊加起來.
下面來張示意圖, 它比較好的解釋了其中3種光照效果組成部分。
環境光(ambient light)
環境光是場景中的基本光源。如果你進入一個漆黑的屋子,環境光通常是零,但走到外面時,總是有光能讓你看到。環境光沒有方向(所以也將其稱為“全局光照模型”).
在室內, 環境通常是經環境散射無法確定方向的光, 就好像來自四面八方的光.
漫射光(diffuse light)
實際看看周圍的桌面,牆面,太陽照射到上面的時候,我們就能看到光,大多數情況下,我們看到的多數光源是漫射光傳播到我們的眼睛。
就像下圖這樣子:
我們平時看到的桌面或者牆壁都是平滑的,那么也就是說n法線都應該是垂直向上才對,也就是說光的反射不一定能傳播進我們的眼睛了?那為什么我們從不同角度看這個桌面,它的漫射光都是一樣的呢?
解決這個問題的關鍵就是:在微觀條件下表面都是粗糙的。
就是如果我們使用顯微鏡觀察一個很平滑的桌面,也會發現是凹凸不平的。凹凸不平到什么程度呢?從所有不同方向和角度都能觀察到其粗糙程度是一樣的。這么思考之后,就可以想通了,微觀法線並不是垂直向上的,而是在不同角度。
鏡面反射光(specular light)
就是平時我們看到的一個光滑球面會發出的耀眼光點。如下圖:
金屬表面,塑料,玻璃,瓶子等容易觀察到這種鏡面反射光.
關於鏡面反射光的幾點說明:
1 球面容易看到鏡面反射光,是因為球面的法線向外擴散,讓看到高亮光的區域更大,那么就更加容易看到鏡面反射光了。
2 鏡面表面很平滑,那么鏡面反射光就會很集中,雖然看到的區域小,但是因為高亮的強度很大,那么就可以很清晰的看到鏡面反射光了。
3 其實鏡面反射光可以發生在任何物體和任何表面上。
4 粗糙的表面鏡面反射光效果很弱或者甚至看不到鏡面反射光
發射光(emitted light)
這種光是一種材質發出來的光,用來模擬物體發出來的光, 在3dsmax中,被稱為自發光材質.
比如一個場景中有個白熾燈泡, 那么這個為這個燈泡就可以賦上"自發光材質"
下圖是3dsmax的光照渲染出來的效果, 按上面的理論, 它應該是由以上四種光源類型疊加出來的.
筆者來給大家分離單獨的光源類型, 看看實際效果是什么樣子.
首先, 環境光(ambient light) , 這個場景是開放的不是室內, 因此我們就不管環境光了.
然后, 發射光(emitted light), 在下面場景中是不存在的. 我們也不管.
我們只研究一下下面場景中的, 漫射光(diffuse light), 鏡面反射光(specular light) 是個什么樣子.
下面是被分離出來的 漫射光(diffuse light)
下面是被分離出來的 鏡面反射光(specular light)
因此,這個場景中的光照,就是由上面兩張圖片所示的 漫射光(diffuse light), 鏡面反射光(specular light) 構成的。
(二)法線向量
法線向量簡稱法線。是垂直於表面的向量。對於一個平面, 所有頂點的法線都是一樣的。 對於曲面,各個頂點的法線方向可能不同。
筆者當初學習3dsmax的時候,總不知道法線是什么,后來學會了3dsmax的法線對齊功能的用法,突然就明白了法線是什么了。
這個法線對齊要求先在要被對齊的對象(下圖是長方體) 的某個面點一下, 系統確定了這個面的法線, 在下圖是長方體頂面上的藍線。
然后再去要對齊到的對象的那個面上點一下,系統又確定了那個面的法線, 在下圖是球面上那根亮綠色的線。
然后,兩個面就按法線相向的姿式對到一齊去了。
不用搬出公式,也不用廢話,你明白了嗎?
法線在3dsmax里面還決定了某個面是否可見, 法線正方向的面你的眼睛可見, 法線反方向的面,你的眼睛就看不見這個面了。
如下面左圖是球體法線正方向對着你的眼睛, 所以其面都可見。 而右圖是球體的法線的正方向在在球的背面,對着你眼睛的是法線反方向,因此前面的面消失了,看到了球內部。
而在OpenGL中,OpenGL是使用法線向量來確定一個物體表面的某個頂點所接受的光照的。如果不想使用OpenGL的光照功能,就可以免去為頂點指定法線向量這個步驟的。
原創文章,出自"博客園, 豬悟能'S博客" : http://www.cnblogs.com/hackpig/