教程
OpenGLES入门教程1-Tutorial01-GLKit
OpenGLES入门教程2-Tutorial02-shader入门
OpenGLES入门教程3-Tutorial03-三维变换
OpenGLES入门教程4-Tutorial04-GLKit进阶
OpenGLES进阶教程1-Tutorial05-地球月亮
OpenGLES进阶教程2-Tutorial06-光线
这次的内容是粒子效果。
效果展示
核心思路
自定义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编译流程图
总结
OpenGL ES的学习需要多尝试,同时有规范的代码习惯,还要对功能进行抽象和封装。
附上源码