前言
最近稍有空閑,整理下之前學習光照的筆記,以及在配置OpenGL4環境過程中遇到的問題。
光照
1、模擬燈光
模擬燈光:通過GPU來計算場景中的幾何圖形投射和散發出來的光線。
本質是GPU對每個三角形的頂點單獨計算燈光,然后把結果再頂點之間的片元中進行插值。
故而當要求一個更真實、更光滑的燈光時,需要增加大量的三角形,從而加大計算量。
在上述這種情況,可以把燈光效果預處理并烘焙到紋理中。(就是形成一個紋理)
2、光照計算
光源=環境光 + 漫反射光 + 鏡面反射光。
在計算光照的過程中,需要注意三角形的材質、三角形的法線、光源的光線;
法向量也是單位向量。
標準化:把向量的長度化為1.0。
3、GLK和光照
與光照相關的GLKBaseEffect屬性:
@property (nonatomic, assign) GLKVector4 position; // { 0.0, 0.0, 0.0, 1.0 }
@property (nonatomic, assign) GLKVector4 ambientColor; // { 0.0, 0.0, 0.0, 1.0 }
@property (nonatomic, assign) GLKVector4 diffuseColor; // { 1.0, 1.0, 1.0, 1.0 }
@property (nonatomic, assign) GLKVector4 specularColor; // { 1.0, 1.0, 1.0, 1.0 }
在開啟燈光后,GLKBaseEffect的常量顏色以及頂點的顏色都會被忽略。
即使設置成燈光關閉,enabled = GL_FALSE ,constantColor仍會被忽略。
求三角形ABC法向量:給出三角形ABC三個頂點的坐標后,通過
GLKVector3Subtract
可以算出兩個向量AB, AC;
通過GLKVector3CrossProduct
求出AB和AC的叉積,并單元化GLKVector3Normalize
。
4、光照模型
我們在現實生活中看到某一物體的顏色并不是這個物體的真實顏色,而是它所反射(Reflected)的顏色。換句話說,那些不能被物體吸收(Absorb)的顏色(被反射的顏色)就是我們能夠感知到的物體的顏色。
這里可以通過vec*vec的方式來計算;
注意三種乘法
- vec * vec 分量乘 (x1 * x2, y1 * y2, z1 * z2) 向量
- vec · vec 點乘 x1*x2 + y1*y2 + z1*z2,標量
- vec X vec 叉乘 (y1 * z2 - z1 * y2 , z1 * x2 - x1 * z2 , x1 * y2 - y1 * x2) 向量
馮氏光照模型(Phong Lighting Model),由3個元素組成:環境光(Ambient)、漫反射光(Diffuse)和鏡面光(Specular) ;
高洛德著色(Gouraud Shading)與馮氏著色(Phong Shading)
在圖形渲染中有兩種著色方式,高洛德著色與馮氏著色。高洛德著色也被稱為Per-Vertex著色,它是在頂點著色階段對頂點進行顏色計算,然后在光柵化階段對這些頂點顏色進行線性插值形成片元的顏色;馮氏著色也被稱為Per-Pixel像素著色,它是在片元著色階段對每一個片元(像素)進行顏色計算。
逆矩陣(Inverse Matrix)和轉置矩陣(Transpose Matrix)
無論何時當我們提交一個不等比縮放(注意:等比縮放不會破壞法線,因為法線的方向沒被改變,而法線的長度很容易通過標準化進行修復),法向量就不會再垂直于它們的表面了,這樣光照會被扭曲。
修復這個行為的訣竅是使用另一個為法向量專門定制的模型矩陣。這個矩陣稱之為正規矩陣(Normal Matrix),它是進行了一點線性代數操作移除了對法向量的錯誤縮放效果。如果你想知道這個矩陣是如何計算出來的。
正規矩陣被定義為“模型矩陣左上角的逆矩陣的轉置矩陣”。
這一段來源是learnopengl
對于著色器來說,逆矩陣也是一種開銷比較大的操作,因此,無論何時,在著色器中只要可能就應該盡量避免逆操作,因為它們必須為你場景中的每個頂點進行這樣的處理。以學習的目的這樣做很好,但是對于一個對于效率有要求的應用來說,在繪制之前,你最好用CPU計算出正規矩陣,然后通過uniform把值傳遞給著色器(和模型矩陣一樣)。
備注:GLK相關的函數如下
GLKMatrix4 GLKMatrix4InvertAndTranspose(GLKMatrix4 matrix, bool * __nullable isInvertible);
光照總結
光照計算的終極公式
光照顏色 = 發射顏色 + 全局環境顏色 + (環境顏色 + 漫反射顏色 + 鏡面反射顏色) × 聚光燈效果 ****× 衰減因子****
OpenGL4環境搭建
learnopengl-cn上有很多不錯的demo,但是在mac運行過程中遇到了各種坑,總結如下。
1、GLFW
如果沒有 GLFW,Xcode 創建的項目只能運行 OpenGL 2.1 的版本,而無法使用系統支持的 4.x 版本。
解決方案
環境配置
2、CMake
sudo "/Applications/CMake.app/Contents/bin/cmake-gui" --install=/usr/local/bin
El Capitan 引入Rootless機制,即使加sudo(也就是具有root權限)也無法修改系統級的目錄,其中就包括了/usr/bin。
解決方案:
- 1、更改Rootless機制
關
csrutil disable
開
csrutil enable
- 2、將鏈接到/usr/bin,改成鏈接到/usr/local/bin。
3、SOIL
SOIL即Simple OpenGL Image Library,是一個跨平臺的支持多個格式圖片加載的庫,主要作用是加載圖片成為OpenGL的texture。
引入過程中一樣帶有很多坑,解決方案如下:
解決方案
4、glm
glm庫是一個C++頭文件形式的幾何數學庫,用于GLSL規范下的圖形繪制。
靠譜的解決方案
注意,glm只有頭文件。
5、OSX
如果你使用的是Mac OSX系統你還需要加下面這行代碼這些配置才能起作用:
glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
總結
已經配置完成的demo在github,里面OpenGL開頭的工程。
最近項目新上了一個手繪禮物的功能,本來打算用OpenGL ES來繪制,后面發現有點大材小用。
下次再單獨開一篇介紹下這個有趣的功能。