下面的這邊文章,讓我對OpenGL中的光照有了新的認識
OpenGL場景中模型顏色的產生,大致為如下的流程圖所描述:
(1)當不開啟光照時,使用頂點顏色來產生整個表面的顏色。
用glShadeModel可以設置表面內部像素顏色產生的方式。GL_FLAT/GL_SMOOTH.
(2)一般而言,開啟光照后,在場景中至少需要有一個光源(GL_LIGHT0.。.GL_LIGHT7)
通過glEnable(GL_LIGHT0) glDisable(GL_LIGHT0) 來開啟和關閉指定的光源。
--- 全局環境光 ---
GLfloat gAmbient[] = {0.6, 0,6, 0,6, 1.0};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, gAmbient);
(3)設置光源的光分量 -- 環境光/漫色光/鏡面光
默認情況下,GL_LIGHT0.。.GL_LIGHT7 的GL_AMBIENT值為(0.0, 0.0, 0.0, 1.0);
GL_LIGHT0的GL_DIFFUSE和GL_SPECULAR值為(1.0, 1.0, 1.0, 1.0),
GL_LIGHT1.。.GL_LIGHT7 的GL_DIFFUSE和GL_SPECULAR值為(0.0, 0.0, 0.0, 0.0)。
GLfloat lightAmbient[] = {1.0, 1.0, 1.0, 1.0};
GLfloat lightDiffuse[] = {1.0, 1.0, 1.0, 1.0};
GLfloat lightSpecular[] = {0.5, 0.5, 0.5, 1.0};
glLightfv(GL_LIGHT0, GL_AMBIENT, lightAmbient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, lightDiffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, lightSpecular);
(4)設置光源的位置和方向
-- 平行光 -- 沒有位置只有方向
GLfloat lightPosition[] = {8.5, 5.0, -2.0, 0.0}; // w=0.0
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
-- 點光源 -- 有位置沒有方向
GLfloat lightPosition[] = {8.5, 5.0, -2.0, 1.0}; // w不為0
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
-- 聚光燈 -- 有位置有方向
GLfloat lightPosition[] = {-6.0, 1.0, 3.0, 1.0}; // w不為0
glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
GLfloat lightDirection[] = {1.0, 1.0, 0.0};
glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, lightDirection); // 聚光燈主軸方向 spot direction
glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0); // cutoff角度 spot cutoff
** 平行光不會隨著距離d增加而衰減,但點光源和聚光燈會發生衰減。
attenuation為衰變系數,系數值越大,衰變越快。
默認情況下,c=1.0, l=0.0, q=0.0
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 2.0); // c 系數
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 1.0); // l 系數
glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.5); // q 系數
++
(5)設置材質屬性
環境光、散射光不受視點位置的影響。物體看起來是什么顏色,很大程度上地受到散射光的影響,環境光反射也對物體的顏色有一定的影響。
因為當光直射物體時,散射光最強;非直射時,環境光效果明顯。對于真實的世界中的物體,其散射光與環境光通常是同一個顏色。
物體的鏡面反射會在物體表面產生一個高亮區。觀察者所看到的鏡面反射依賴于視點位置 -- 沿著反射光的方向亮度最高。
默認情況下,材質的GL_AMBIENT值為(0.2, 0.2, 0.2, 1.0);GL_DIFFUSE值為(0.8, 0.8, 0.8, 1.0);
GL_SPECULAR值為(0.0, 0.0, 0.0, 1.0);GL_SHININESS值為0.0【取值范圍為[0.0, 128.0],數值越大,高亮區越小,亮度越高】;
GL_GL_EMISSION值為(0.0, 0.0, 0.0, 1.0)
GLfloat matAmbient[] = {0.6, 0.6, 0.6, 1.0};
GLfloat matDiffuse[] = {0.35, 0.35, 0.35, 1.0};
GLfloat matAmbDif[] = {0.5, 0.5, 0.5, 1.0};
GLfloat matSpecular[] = {0.2, 0.2, 0.2, 1.0};
GLfloat shine[] = {5.0};
GLfloat matEmission[] = {0.3, 0.1, 0.1, 1.0};
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, matAmbient);
glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, matDiffuse);
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, matAmbDif); // 將背景顏色和散射顏色設置成同一顏色
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, matSpecular);
glMaterialfv(GL_FRONT, GL_SHININESS, shine);
glMaterialfv(GL_FRONT, GL_EMISSION, matEmission); // 用來模擬物體發光的效果,但這不是光源
(6)顏色材質模式
使用顏色材質可以用較小的代價,快速改變場景中模型的顏色。其具體用法如下:
glEnable(GL_COLOR_MATERIAL);
glColorMaterial(GL_FRONT, GL_DIFFUSE);
glColor3f(0.2, 0.5, 0.8);
/*** 繪制一些物體 ***/
glColorMaterial(GL_FRONT, GL_SPECULAR);
glColor3f(0.9, 0.1, 0.3);
/*** 繪制另外一些物體 ***/
glDisable(GL_COLOR_MATERIAL);
評論
查看更多