鍍金池/ 教程/ Android/ 設(shè)置光照效果 Set Lighting
繪制線段 Line Segment
投影變換 Projection
繪制迷你太陽系
繪制一個球體
繪制三角形 Triangle
OpenGL 光照模型
三維坐標(biāo)系及坐標(biāo)變換初步
定義 3D 模型的前面和后面
繪制一個 20 面體
顏色 Color
Depth Buffer
材質(zhì)及光照示例
基本幾何圖形定義
關(guān)于EGL
導(dǎo)言
Viewing 和 Modeling(MODELVIEW) 變換
FrameBuffer
設(shè)置光照效果 Set Lighting
Viewport 變換
階段小結(jié)
繪制點 Point
OpenGL ES API 命名習(xí)慣
通用的矩陣變換指令
關(guān)于 OpenGL ES
創(chuàng)建實例應(yīng)用 OpenGLDemos 程序框架
OpenGL ES 管道(Pipeline)
GLSurfaceView

設(shè)置光照效果 Set Lighting

上一篇簡單介紹了 OpenGL 中使用的光照模型,本篇結(jié)合 OpenGL ES API 說明如何使用光照效果:

  • 設(shè)置光源
  • 定義法線
  • 設(shè)置物體材料光學(xué)屬性

光源

OpenGL ES 中可以最多同時使用八個光源,分別使用0到7表示。

OpenGL ES光源可以分為

  • 平行光源(Parallel light source), 代表由位于無限遠(yuǎn)處均勻發(fā)光體,太陽可以近似控制平行光源。
  • 點光源(Spot light source)如燈泡就是一個點光源,發(fā)出的光可以指向360度,可以為點光源設(shè)置光衰減屬性(attenuation)或者讓點光源只能射向某個方向(如射燈)。
  • 可以為圖形的不同部分設(shè)置不同的光源。

下面方法可以打開某個光源,使用光源首先要開光源的總開關(guān):

gl.glEnable(GL10.GL_LIGHTING);

然后可以再打開某個光源如0號光源:

gl.glEnable(GL10.GL_LIGHTI0);

設(shè)置光源方法如下:

  • public void glLightfv(int light,int pname, FloatBuffer params)
  • public void glLightfv(int light,int pname,float[] params,int offset)
  • public void glLightf(int light,int pname,float param)
  • light 指光源的序號,OpenGL ES可以設(shè)置從0到7共八個光源。
  • pname: 光源參數(shù)名稱,可以有如下:GL_SPOT_EXPONENT, GL_SPOT_CUTOFF, GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION, GL_AMBIENT, GL_DIFFUSE,GL_SPECULAR, GL_SPOT_DIRECTION, GL_POSITION
  • params 參數(shù)的值(數(shù)組或是Buffer類型)。

其中為光源設(shè)置顏色的參數(shù)類型為 GL_AMBIENT,GL_DIFFUSE,GL_SPECULAR,可以分別指定R,G,B,A 的值。

指定光源的位置的參數(shù)為 GL_POSITION,值為(x,y,z,w):

平行光將 w 設(shè)為0.0,(x,y,z)為平行光的方向:

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/96.png" alt="" />

對于點光源,將 w 設(shè)成非0值,通常設(shè)為1.0. (x,y,z)為點光源的坐標(biāo)位置。

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/97.png" alt="" />

將點光源設(shè)置成聚光燈,需要同時設(shè)置 GL_SPOT_DIRECTION,GL_SPOT_CUTOFF 等參數(shù),GL_POSITION的設(shè)置和點光源類似:將 w 設(shè)成非0值,通常設(shè)為1.0. (x,y,z)為點光源的坐標(biāo)位置。而對于GL_SPOT_DIRECTION 參數(shù),設(shè)置聚光的方向(x,y,z)

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/98.png" alt="" />

GL_SPOT_CUTOFF 參數(shù)設(shè)置聚光等發(fā)散角度(0到90度)

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/99.png" alt="" />

GL_SPOT_EXPONENT 給出了聚光燈光源匯聚光的程度,值越大,則聚光區(qū)域越?。ň酃饽芰Ω鼜姡?/p>

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/100.png" alt="" />

對應(yīng)點光源(包括聚光燈),其它幾個參數(shù) GL_CONSTANT_ATTENUATION, GL_LINEAR_ATTENUATION, GL_QUADRATIC_ATTENUATION 為點光源設(shè)置光線衰減參數(shù),公式有如下形式,一般無需詳細(xì)了解:

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/101.png" alt="" />

在場景中設(shè)置好光源后,下一步要為所繪制的圖形設(shè)置法線(Normal),只有設(shè)置了法線,光源才能在所會物體上出現(xiàn)光照效果。三維平面的法線是垂直于該平面的三維向量。曲面在某點P處的法線為垂直于該點切平面的向量

http://wiki.jikexueyuan.com/project/opengl-es-guide/images/102.png" alt="" />

和設(shè)置顏色類似,有兩個方法可以為平面設(shè)置法線,一是

public void glNormal3f(float nx,float ny,float nz)

這個方法為后續(xù)所有平面設(shè)置同樣的方向,直到重新設(shè)置新的法線為止。

為某個頂點設(shè)置法線:

public void glNormalPointer(int type,int stride, Buffer pointer)
  • type 為Buffer 的類型,可以為GL_BYTE, GL_SHORT, GL_FIXED,或 GL_FLOAT
  • stride: 每個參數(shù)之間的間隔,通常為0.
  • pointer: 法線值。

打開法線數(shù)組

gl.glEnableClientState(GL10.GL\_NORMAL\_ARRAY);  

用法和 Color, Vertex 類似。參見 Android OpenGL ES 開發(fā)教程(8):基本幾何圖形定義

規(guī)范化法向量,比如使用坐標(biāo)變換(縮放),如果三個方向縮放比例不同的話,頂點或是平面的法線可能就有變好,此時需要打開規(guī)范化法線設(shè)置:

gl.glEnable(GL10.GL\_NORMALIZE);  

經(jīng)過規(guī)范化后法向量為單位向量(長度為1)。同時可以打開縮放法線設(shè)置

gl.glEnable(GL10.GL\_RESCALE\_NORMAL);  

設(shè)置好法線后,需要設(shè)置物體表面材料(Material)的反光屬性(顏色和材質(zhì))。

將在下篇介紹設(shè)置物體表面材料(Material)的反光屬性(顏色和材質(zhì))并給出一個光照的示例。