教程
OpenGLES入門教程1-Tutorial01-GLKit
OpenGLES入門教程2-Tutorial02-shader入門
OpenGLES入門教程3-Tutorial03-三維變換
OpenGLES入門教程4-Tutorial04-GLKit進(jìn)階
OpenGLES進(jìn)階教程1-Tutorial05-地球月亮
OpenGLES進(jìn)階教程2-Tutorial06-光線
這次的內(nèi)容是粒子效果。
效果展示

核心思路
自定義shader著色器
通過(guò)glCreateProgram()創(chuàng)建shader。圖形變換
GLKMatrix4MakeLookAt實(shí)現(xiàn)模型變換
GLKMatrix4MakePerspective實(shí)現(xiàn)透視變換粒子效果
glDrawArrays的GL_POINTS參數(shù)可以用來(lái)畫粒子
glsl的頂點(diǎn)著色有內(nèi)建變量gl_PointSize,可以用來(lái)設(shè)置粒子大小物理
通過(guò)a = f/m算加速度
v = v0 + at 算速度
s = s0 + 0.5 * (v0 + v) * t 算距離
具體細(xì)節(jié)
-
AGLKPointParticleEffect類
AGLKPointParticleEffect類管理并且繪制所有的粒子。
- (void)addParticleAtPosition:(GLKVector3)aPosition
velocity:(GLKVector3)aVelocity
force:(GLKVector3)aForce
size:(float)aSize
lifeSpanSeconds:(NSTimeInterval)aSpan
fadeDurationSeconds:(NSTimeInterval)aDuration;
添加一個(gè)粒子的方法,參數(shù)包括初始速度、受力、大小、持續(xù)時(shí)間、漸隱時(shí)間,** 注意 ** 粒子會(huì)根據(jù)生命周期進(jìn)行復(fù)用。
loadShaders 方法是加載shader
prepareToDraw方法緩存頂點(diǎn)數(shù)據(jù)、為頂點(diǎn)著色器的變量賦值
- AGLKPointParticleShader類
代碼注釋非常詳細(xì)
attribute vec3 a_emissionPosition; //位置
attribute vec3 a_emissionVelocity; //速度
attribute vec3 a_emissionForce; //受力
attribute vec2 a_size; //大小 和 Fade持續(xù)時(shí)間 size = GLKVector2Make(aSize, aDuration);
attribute vec2 a_emissionAndDeathTimes; //發(fā)射時(shí)間 和 消失時(shí)間
// UNIFORMS
uniform highp mat4 u_mvpMatrix; //變換矩陣
uniform sampler2D u_samplers2D[1]; //紋理
uniform highp vec3 u_gravity; //重力
uniform highp float u_elapsedSeconds; //當(dāng)前時(shí)間
// Varyings
varying lowp float v_particleOpacity; //粒子 不透明度
void main()
{
highp float elapsedTime = u_elapsedSeconds - a_emissionAndDeathTimes.x; //流逝時(shí)間
// 質(zhì)量假設(shè)是1.0 加速度 = 力 (a = f/m)
// v = v0 + at : v 是當(dāng)前速度; v0 是初速度;
// a 是加速度; t 是時(shí)間
highp vec3 velocity = a_emissionVelocity +
((a_emissionForce + u_gravity) * elapsedTime);
// s = s0 + 0.5 * (v0 + v) * t : s 當(dāng)前位置
// s0 初始位置
// v0 初始速度
// v 當(dāng)前速度
// t 是時(shí)間
// 運(yùn)算是對(duì)向量運(yùn)算,相當(dāng)于分別求出x、y、z的位置,再綜合
highp vec3 untransformedPosition = a_emissionPosition +
0.5 * (a_emissionVelocity + velocity) * elapsedTime;
//得出點(diǎn)的位置
gl_Position = u_mvpMatrix * vec4(untransformedPosition, 1.0);
gl_PointSize = a_size.x / gl_Position.w;
// 消失時(shí)間減去當(dāng)前時(shí)間,得到當(dāng)前的壽命; 除以Fade持續(xù)時(shí)間,當(dāng)剩余時(shí)間小于Fade時(shí)間后,得到一個(gè)從1到0變化的值
// 如果這個(gè)值小于0,則取0
v_particleOpacity = max(0.0, min(1.0,
(a_emissionAndDeathTimes.y - u_elapsedSeconds) /
max(a_size.y, 0.00001)));
}
shader編譯流程圖

總結(jié)
OpenGL ES的學(xué)習(xí)需要多嘗試,同時(shí)有規(guī)范的代碼習(xí)慣,還要對(duì)功能進(jìn)行抽象和封裝。
附上源碼