教程
OpenGLES入门教程1-Tutorial01-GLKit
OpenGLES入门教程2-Tutorial02-shader入门
OpenGLES入门教程3-Tutorial03-三维变换
OpenGLES入门教程4-Tutorial04-GLKit进阶
OpenGLES进阶教程1-Tutorial05-地球月亮
OpenGLES进阶教程2-Tutorial06-光线
这次的内容是粒子效果。
效果展示
粒子效果.gif
核心思路
- 自定义shader着色器 通过glCreateProgram()创建shader。
- 图形变换 GLKMatrix4MakeLookAt实现模型变换 GLKMatrix4MakePerspective实现透视变换
- 粒子效果 glDrawArrays的GL_POINTS参数可以用来画粒子 glsl的顶点着色有内建变量gl_PointSize,可以用来设置粒子大小
- 物理 通过a = f/m算加速度 v = v0 at 算速度 s = s0 0.5 * (v0 v) * t 算距离
具体细节
- AGLKPointParticleEffect类 AGLKPointParticleEffect类管理并且绘制所有的粒子。
- (void)addParticleAtPosition:(GLKVector3)aPosition
velocity:(GLKVector3)aVelocity
force:(GLKVector3)aForce
size:(float)aSize
lifeSpanSeconds:(NSTimeInterval)aSpan
fadeDurationSeconds:(NSTimeInterval)aDuration;
添加一个粒子的方法,参数包括初始速度、受力、大小、持续时间、渐隐时间,** 注意 ** 粒子会根据生命周期进行复用。
loadShaders
方法是加载shader
prepareToDraw
方法缓存顶点数据、为顶点着色器的变量赋值
- AGLKPointParticleShader类 代码注释非常详细
attribute vec3 a_emissionPosition; //位置
attribute vec3 a_emissionVelocity; //速度
attribute vec3 a_emissionForce; //受力
attribute vec2 a_size; //大小 和 Fade持续时间 size = GLKVector2Make(aSize, aDuration);
attribute vec2 a_emissionAndDeathTimes; //发射时间 和 消失时间
// UNIFORMS
uniform highp mat4 u_mvpMatrix; //变换矩阵
uniform sampler2D u_samplers2D[1]; //纹理
uniform highp vec3 u_gravity; //重力
uniform highp float u_elapsedSeconds; //当前时间
// Varyings
varying lowp float v_particleOpacity; //粒子 不透明度
void main()
{
highp float elapsedTime = u_elapsedSeconds - a_emissionAndDeathTimes.x; //流逝时间
// 质量假设是1.0 加速度 = 力 (a = f/m)
// v = v0 at : v 是当前速度; v0 是初速度;
// a 是加速度; t 是时间
highp vec3 velocity = a_emissionVelocity
((a_emissionForce u_gravity) * elapsedTime);
// s = s0 0.5 * (v0 v) * t : s 当前位置
// s0 初始位置
// v0 初始速度
// v 当前速度
// t 是时间
// 运算是对向量运算,相当于分别求出x、y、z的位置,再综合
highp vec3 untransformedPosition = a_emissionPosition
0.5 * (a_emissionVelocity velocity) * elapsedTime;
//得出点的位置
gl_Position = u_mvpMatrix * vec4(untransformedPosition, 1.0);
gl_PointSize = a_size.x / gl_Position.w;
// 消失时间减去当前时间,得到当前的寿命; 除以Fade持续时间,当剩余时间小于Fade时间后,得到一个从1到0变化的值
// 如果这个值小于0,则取0
v_particleOpacity = max(0.0, min(1.0,
(a_emissionAndDeathTimes.y - u_elapsedSeconds) /
max(a_size.y, 0.00001)));
}
shader编译流程图
Paste_Image.png
总结
OpenGL ES的学习需要多尝试,同时有规范的代码习惯,还要对功能进行抽象和封装。
附上源码