教程
- OpenGLES入門教程1-Tutorial01-GLKit
- OpenGLES入門教程2-Tutorial02-shader入門
- OpenGLES入門教程3-Tutorial03-三維變換
- OpenGLES入門教程4-Tutorial04-GLKit進(jìn)階
- OpenGLES進(jìn)階教程1-Tutorial05-地球月亮
這一次的的內(nèi)容是光照。
概念準(zhǔn)備
所謂的光照照捡,是GPU為每個(gè)三角形的頂點(diǎn)進(jìn)行光線計(jì)算,再把結(jié)果進(jìn)行插值每庆,得出每個(gè)片元的最終顏色奥裸。
OpenGL ES的燈光模擬包括:環(huán)境光、漫反射光、鏡面反射光亡哄。
光線與幾何圖形相互作用的關(guān)鍵:計(jì)算出每個(gè)物體照射和發(fā)散出來多少光線。
光線計(jì)算依賴于表面法向量布疙。法向量也是單位向量蚊惯。
表面法向量可以通過平面內(nèi)兩個(gè)點(diǎn)的叉積(矢量積)來計(jì)算。
光線計(jì)算過程還包括材質(zhì)灵临、聚光燈效果截型、衰減因子等,但是GLKit簡化了這一過程儒溉。
效果展示
核心思路
如下圖宦焦,總共AI九個(gè)點(diǎn),07八個(gè)面。E的z坐標(biāo)是可變的波闹,隨著UISlider的數(shù)值由-1到0變化酝豪。
為了方便觀察,繞X軸和Z軸旋轉(zhuǎn)了一定角度精堕。
燈光用GLKBaseEffect類孵淘。
具體細(xì)節(jié)
- 頂點(diǎn)
總共有9個(gè)頂點(diǎn),具體坐標(biāo)如下歹篓。前面為頂點(diǎn)坐標(biāo)瘫证,后面為法線坐標(biāo)。
static const SceneVertex vertexA = {{-0.5, 0.5, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexB = {{-0.5, 0.0, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexC = {{-0.5, -0.5, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexD = {{ 0.0, 0.5, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexE = {{ 0.0, 0.0, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexF = {{ 0.0, -0.5, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexG = {{ 0.5, 0.5, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexH = {{ 0.5, 0.0, -0.5}, {0.0, 0.0, 1.0}};
static const SceneVertex vertexI = {{ 0.5, -0.5, -0.5}, {0.0, 0.0, 1.0}};
重新緩存頂點(diǎn)數(shù)組
- 平面
SceneVertex是頂點(diǎn)的數(shù)據(jù)結(jié)構(gòu)
SceneTriangle是平面(三角形)的數(shù)據(jù)結(jié)構(gòu)
//頂點(diǎn)
typedef struct {
GLKVector3 position; //
GLKVector3 normal;
}
SceneVertex;
//三角形
typedef struct {
SceneVertex vertices[3];
}
SceneTriangle;
- 光源
配置漫反射光的顏色庄撮,還有光源的位置
self.baseEffect = [[GLKBaseEffect alloc] init];
self.baseEffect.light0.enabled = GL_TRUE;
self.baseEffect.light0.diffuseColor = GLKVector4Make(
0.7f, // Red
0.7f, // Green
0.7f, // Blue
1.0f);// Alpha
self.baseEffect.light0.position = GLKVector4Make(
1.0f,
1.0f,
0.5f,
0.0f);
self.extraEffect = [[GLKBaseEffect alloc] init];
self.extraEffect.useConstantColor = GL_TRUE;
- 變換
先旋轉(zhuǎn)痛悯,后平移
GLKMatrix4 modelViewMatrix = GLKMatrix4MakeRotation(GLKMathDegreesToRadians(-60.0f), 1.0f, 0.0f, 0.0f);
modelViewMatrix = GLKMatrix4Rotate(
modelViewMatrix,
GLKMathDegreesToRadians(-30.0f), 0.0f, 0.0f, 1.0f);
modelViewMatrix = GLKMatrix4Translate(
modelViewMatrix,
0.0f, 0.0f, 0.25f);
self.baseEffect.transform.modelviewMatrix = modelViewMatrix;
self.extraEffect.transform.modelviewMatrix = modelViewMatrix;
- 法線繪制
先設(shè)置光源顏色為綠色,畫頂點(diǎn)法線
再設(shè)置光源顏色為黃色重窟,畫光源線
self.extraEffect.useConstantColor = GL_TRUE;
self.extraEffect.constantColor =
GLKVector4Make(0.0, 1.0, 0.0, 1.0);
[self.extraEffect prepareToDraw];
[self.extraBuffer drawArrayWithMode:GL_LINES
startVertexIndex:0
numberOfVertices:NUM_NORMAL_LINE_VERTS];
self.extraEffect.constantColor =
GLKVector4Make(1.0, 1.0, 0.0, 1.0);
[self.extraEffect prepareToDraw];
[self.extraBuffer drawArrayWithMode:GL_LINES
startVertexIndex:NUM_NORMAL_LINE_VERTS
numberOfVertices:(NUM_LINE_VERTS - NUM_NORMAL_LINE_VERTS)];
關(guān)鍵函數(shù)
- 求法向量函數(shù)
GLKVector3 SceneTriangleFaceNormal(const SceneTriangle triangle);
- 通過叉積求單位法向量函數(shù)
GLKVector3 SceneVector3UnitNormal(
const GLKVector3 vectorA,
const GLKVector3 vectorB)
總結(jié)
進(jìn)階教程不只是圖形學(xué)知識的進(jìn)階载萌,代碼的規(guī)范也很重要,能避免一部分錯(cuò)誤巡扇。
光照原理的內(nèi)容可以參考這里扭仁,講解非常詳細(xì),但是本次使用的GLKit厅翔,所以簡化了許多乖坠。
附上源碼