前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >iOS开发-OpenGLES进阶教程3

iOS开发-OpenGLES进阶教程3

作者头像
落影
发布2018-04-27 15:13:27
1.1K0
发布2018-04-27 15:13:27
举报
文章被收录于专栏:落影的专栏落影的专栏

教程

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的学习需要多尝试,同时有规范的代码习惯,还要对功能进行抽象和封装。

附上源码

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016.04.21 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 教程
  • 效果展示
  • 核心思路
  • 具体细节
  • shader编译流程图
  • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档