粒子效果研究

2019-03-31  本文已影响0人  小人物灌篮

粒子系统(Particle System)

粒子系统表示三维计算机图形学中模拟一些特定的模糊现象的技术,而这些现象用其它传统的渲染技术难以实现的真实感的游戏图形。经常使用粒子系统模拟的现象,有火、爆炸、烟、水流、火花、落叶、云、雾、雪、尘、流星尾迹或者象发光轨迹这样的抽象视觉效果等等。

粒子系统的特点

  1. 整个现象都是由很多个独立的图像效果组成,这些图像效果都有自己的位置、移动轨迹等特点;
  2. 这些独立的图像效果组合或者叠加起来,就形成了要模拟的现象;
  3. 独立的图像效果经过一段生命周期之后会从屏幕上消失,进而可以将其状态重置并重新利用;

粒子系统的组成

属性设置

粒子系统中可以设置的属性如下所示,不同平台可能略有差异,但所遵守的标准相同,所以基本大同小异。

属性设置.png

Cocos使用OpenGL混合原理对图形进行渲染绘制。混合就是指把两种颜色混在一起,具体一点就是把某一像素位置原来的颜色和将要画上去的颜色,通过某种方式混在一起,从而实现特殊的效果。它是一种常用的技巧,通常可以用来实现半透明,你也可以通过不同的设置得到不同的混合结果,产生一些有趣或者奇怪的图象。具体可以参考:
https://www.andersriggelsen.dk/glblendfunc.php,下面是混合的集中模式,可以作用于src,

BlendFactor枚举类型及其作用。

含义 作用
ONE 全部使用
ZERO 全部不用
SRC_ALPHA 使用源颜色的透明度
SRC_COLOR 使用源颜色
DST_ALPHA 使用目标颜色的透明度
DST_COLOR 使用目标颜色
ONE_MINUS_SRC_ALPHA 减去源颜色的透明度
ONE_MINUS_SRC_COLOR 减去源颜色
ONE_MINUS_DST_ALPHA 减去目标颜色的透明度
ONE_MINUS_DST_COLOR 减去目标颜色

关于粒子在cocos中的使用。

cocos create中提供了界面友好的工具供我们使用,粒子的简单使用可以参考: https://docs.cocos.com/creator/manual/zh/asset-workflow/particle.html
我们可以在cocos中编辑这些粒子效果,在编辑的过程中可以预览到粒子的实时效果,粒子相关的特性基本在plist中声明即可。

粒子属性.png

如果我们需要在cocos中通过代码的形式控制到粒子动画的播放和停止的话,可以resetSystem()来控制器展现,利用stopSystem控制其隐藏。示例代码如下:

//mA 表示要控制的粒子 ,即  mA: cc.ParticleSystem;
if(this.mA.active) {  
    this.mA.stopSystem();
} else {
    this.mA.resetSystem();
}

关于颜色计算

关于cocos源码的实现

ParticleTest 测试类入口。
CCParticleExamples 测试主体类,主要在这里实现。

CCParticleSystem 是粒子系统的基类,提供对粒子的创建和更新管理。
ParticleSystemQuadCCParticleSystem 的子类,实现不需要批次结点时也能够实现粒子系统的OPENGL顶点和索引缓冲的创建和渲染.
CCParticleBatchNode 粒子系统的批次节点,用于将使用相同纹理的粒子系统进行同批次渲染优化处理。

粒子系统实现类在CCParticleSystem中,其中包含了粒子系统的大部分实现,下面是粒子系统中的几个重要方法实现。

将粒子添加到粒子系统的实现(*)

这个是整个粒子系统运行的必要条件,想要粒子系统运行起来,必须得先将粒子加入到粒子系统中。相关代码也比较复杂,比较多。
这里就不贴出具体的代码,只给出关键的代码:

void ParticleSystem::addParticles(int count)
{
    //life
    //position
    //color
    //size
    // rotation
    // position
    // Mode Gravity: 
    针对上面的属性做赋值处理
}

粒子更新的实现

// ParticleSystem - MainLoop
void ParticleSystem::update(float dt)
{

    // 省略了一些属性的设置调整。

    // 需要被重载的更新粒子的对应矩形顶点缓冲信息块的虚函数,在这里进行界面更新
        updateParticleQuads();
        _transformSystemDirty = false;

    if (_visible && ! _batchNode)
    {
        postStep();
    }
}

粒子的属性的动态设置都会在update中来完成,然后利用updateParticleQuads来更新指定粒子的顶点缓冲中的位置数据,他的具体实现在CCParticleSystemQuad垒中,那么postStep做了什么呢,我们来看他的实现,同样,他的实现也在CCParticleSystemQuad中,

//针对不使用批次结点时的VBO顶点缓冲的更新。
void ParticleSystemQuad::postStep()
{
    //绑定顶点缓冲区对象。 
    glBindBuffer(GL_ARRAY_BUFFER, _buffersVBO[0]);
    
    //用_quads中数据更新绑定的缓冲区数据。
    // Option 1: Sub Data
    glBufferSubData(GL_ARRAY_BUFFER, 0, sizeof(_quads[0])*_totalParticles, _quads);
    
    // Option 2: Data
    //  glBufferData(GL_ARRAY_BUFFER, sizeof(quads_[0]) * particleCount, quads_, GL_DYNAMIC_DRAW);
    
    // Option 3: Orphaning + glMapBuffer
    // glBufferData(GL_ARRAY_BUFFER, sizeof(_quads[0])*_totalParticles, nullptr, GL_STREAM_DRAW);
    // void *buf = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY);
    // memcpy(buf, _quads, sizeof(_quads[0])*_totalParticles);
    // glUnmapBuffer(GL_ARRAY_BUFFER);
    
    //取消绑定缓冲区对象。
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    CHECK_GL_ERROR_DEBUG();
}

停止粒子系统的实现

这个实现就很简单了,主要把_isActive设置为false即可。把开始到当前的运行秒数_elapsed_duration赋值, 然后把每秒发射的粒子数_elapsed置为0,代码如下:

void ParticleSystem::stopSystem()
{
    _isActive = false;
    _elapsed = _duration;
    _emitCounter = 0;
}

粒子重新启动的实现

粒子系统重新启动的实现也很简单,主要是把所有的粒子的生命值置为0。

void ParticleSystem::resetSystem()
{
    _isActive = true;
    _elapsed = 0;
    for (int i = 0; i < _particleCount; ++i)
    {
        _particleData.timeToLive[i] = 0.0f;
    }
}

关于粒子系统属性的设置

cocos 支持两种方式的属性设置,一种是通过字典,一种是通过plist文件。
通过字典的方式,就是手动去将元素的值赋值给字典,然后通过initWithDictionary方法来实现赋值,这种方式比较麻烦,而且也比较容易遗漏,所以我们一般采用第二种方式,即通过plist文件的形式来赋值。我们可以借助其他工具,生成plist文件,然后通过ParticleSystem::initWithFile来读取这个文件,进行赋值。

术语

混合就是把两种颜色混在一起。
具体一点,就是把某一像素位置原来的颜色和将要画上去的颜色,通过某种方式混在一起,从而实现特殊的效果。

假设我们需要绘制这样一个场景:透过红色的玻璃去看绿色的物体,那么可以先绘制绿色的物体,再绘制红色玻璃。在绘制红色玻璃的时候,利用“混合”功能,把将要绘制上去的红色和原来的绿色进行混合,于是得到一种新的颜色,看上去就好像玻璃是半透明的。

前面我们已经提到,混合需要把原来的颜色和将要画上去的颜色找出来,经过某种方式处理后得到一种新的颜色。这里把将要画上去的颜色称为“源颜色”,如上例中的红色;把原来的颜色称为“目标颜色”,如上例中的绿色。

目的颜色:先画上的颜色(相当于内容)。
源颜色: 后画上去的颜色(相当于背景)。

VAO 用于存储顶点数据,包括顶点颜色、坐标、法线,以及顶点的indices。
VBO 用于存储图形处理器将怎么使用VBO里面的数据,及顶点数据中哪些是坐标、哪些是颜色、哪些是法线等信息。

参考

上一篇 下一篇

猜你喜欢

热点阅读