向場景中添加光照的4個步驟:
1)爲每個物體的每個頂點計算法向量,法線確定了物體相對於光源的指向
法線的計算:設向量a(x1,y1,z1),向量b(x2,y2,z2)
則a×b=(x2·y3-x3·y2,x3·y1-x1·y3,x1·y2-x2·y1)
2)創建、選擇並定位所有的光源
光源的創建:
glLight*()函數可以定義光的一些屬性——顏色、位置、方向
定義光時,此族函數最長用的一種形式是:
void glLightfv(Glenum light,Glenum pname,TYPE* param)
此函數中三個參數:所要爲其指定屬性的光、所要指定的屬性、此屬性的值
參數light的值可以是GL_LIGHT0~GL_LIGHT7,指定了要對那個光進行設置
參數所定義的屬性或特性如下表所示:
param是一個浮點型數組,例如:
float ambientLight[]={ 1.0f, 1.0f, 1.0f, 1.0f };
glLightfv(GL_LIGHT0,GL_AMBIENT,ambientLight);
此處定義了一個具有亮白的環境光分量的光源
注意:在指定一個環境光屬性時,同時也指定了此光在此場景中所添加的環境光RGBA的強度,
默認條件下是沒有環境光的,其默認值爲(0.0f,0.0f,0.0f,1.0f);
光源的定位:
光源的位置是以GL_POSITION和一個四個值的矢量(x,y,z,w)來定義的。
如果w的值爲0.0,那麼(x,y,z)的值就定義了一個矢量,其指定了光線照過來的方向,
且所有的光線都是平行的,就好像光源處於無窮遠處。
如果w的值爲非零,所定義的就是一個定點光源
例如:float lightPosition[]={0.0f,0.0f.0.0f,1.0f};
glLghtfv(GL_LIGHT0,GL_POSITION,lightPosition);
定義了一個位於世界座標原點的定點光源。
而對於光的衰減、光柱的張角、聚光燈的焦點的設置,我們常用glLightf()函數
glLightf(GL_LIGHT0,GL_CONSTANT_ATTENUATION,4.0)//光的衰減
glLightf(GL_LIGHT0,GL_SPOT_CUTOFF,15.0f);//30°光柱張角
glLightf(GL_LIGHT0,GL_SPOT_EXPONENT,10.0F);//指定聚光燈的焦點
3)創建並選擇一種光照模型。光照模型定義了環境光,並設置用於光照計算的視點的位置
OpenGL的光照模型允許設置四個影響場景的因素
- 場景的環境光強度
- 視點是否處於無窮遠(影響鏡面發射光反射角的計算)
- 單面光照還是雙面光照
- 鏡面反射的顏色是否與環境光顏色和反射光顏色分離
可以使用glLightModel*()函數來定義光照模型
void glLightModel[if](GLenum pname,TYPE param);
void glLightModel[if]v(GLenum pname,TYPE param);
例如:將全局環境光設置爲中等亮度的白光
float ambienLighttModel[]={0.5f,0.5f,0.5f,1.0f};
glLightModelfv(GL_LIGHT_MODEL_AMBIENT,ambientLightModel);
4)爲場景中的物體定義材質屬性
實質上與創建光源相似,只是使用的函數不同
void glMaterialf(GLenum face,GLenum pname,TYPE param);
void glMaterialfv(GLenum face,GLenum pname,TYPE* param);
face 的值可以是GL_FRONT,GL_BACK,GL_FRONT_AND_BACK
pname通知OPENGL要設置材質的哪一屬性,下表列出了可能值
例如:給多邊形正、背面材質的環境光顏色設置爲紅色
float red[]={1.0f,0.0f,0.0f,1.0f};
glMaterialfv(GL_FRONT_AND_BACK,GL_AMBIENT,red);
分享一下旋轉燈光的小程序: 下載
程序運行環境:vs2013+OpenGL
在結束之前,送大家一句話(和大家共勉):
——表面繁榮未必是好事,拋開表象看實質纔是人生真諦