OpenGL光照學習以及OpenGL4環境

前言

最近稍有空閑,整理下之前學習光照的筆記,以及在配置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

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。
引入過程中一樣帶有很多坑,解決方案如下:
解決方案

修改圖片中的標志,m64改為x86_64

4、glm

glm庫是一個C++頭文件形式的幾何數學庫,用于GLSL規范下的圖形繪制。
靠譜的解決方案

注意,glm只有頭文件。

5、OSX

如果你使用的是Mac OSX系統你還需要加下面這行代碼這些配置才能起作用:

glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
最后成果

總結

已經配置完成的demo在github,里面OpenGL開頭的工程。
最近項目新上了一個手繪禮物的功能,本來打算用OpenGL ES來繪制,后面發現有點大材小用。
下次再單獨開一篇介紹下這個有趣的功能。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容