iOS开发-OpenGLES进阶教程3

2018-04-27 15:13:27 浏览数 (1)

教程

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类管理并且绘制所有的粒子。
代码语言:javascript复制
- (void)addParticleAtPosition:(GLKVector3)aPosition
   velocity:(GLKVector3)aVelocity
   force:(GLKVector3)aForce
   size:(float)aSize
   lifeSpanSeconds:(NSTimeInterval)aSpan
   fadeDurationSeconds:(NSTimeInterval)aDuration;

添加一个粒子的方法,参数包括初始速度、受力、大小、持续时间、渐隐时间,** 注意 ** 粒子会根据生命周期进行复用。

loadShaders 方法是加载shader

prepareToDraw方法缓存顶点数据、为顶点着色器的变量赋值

  • AGLKPointParticleShader类 代码注释非常详细
代码语言:javascript复制
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的学习需要多尝试,同时有规范的代码习惯,还要对功能进行抽象和封装。

附上源码

0 人点赞