粒子系统简介

一、粒子是什么?

以我个人的理解,粒子就是一个最小单元,粒子系统就是若干个粒子单元。先构造出最小单元,然后复制多个,添加一些不同变换,就可以实现粒子系统的多样性,构造出不同的最小单元,就是粒子的多样性了。

二、粒子的工作原理

从单个粒子出发,从产生到结束,是有生命周期的,可以通过时间加以限制。当然也有长期存在的粒子,没有生命周期的。粒子从产生,绕一个指定的轨迹运动,通过限制一个频率,每隔一段时间产生一批粒子,就这样一直运转下去。

三、粒子多样性

1.最简单的圆球,矩形等等

这种用于实现一些烟花效果,通过简单辉光的办法,做出闪闪发光的效果。

2.绘制的一些图形

一般可以是花瓣,或者树叶等可简单绘制的具有规则的图形,当然,如果多费些功夫,可以绘制复杂的图形,比如花朵,雪花等。

3.通过纹理导入的图片

这种其实是在第二种的基础上发展的,但是这种可能需要费一些功夫,因为粒子都是按中心来定位置,如果是不规则的纹理图案,中心就不太好确定了。

四、粒子系统的多样性

单个粒子,复制若干个就成了粒子系统,可是单纯的复制并不能体现多样性。为了体现多样性,需要尽可能的让每一个粒子都不一样。

1.颜色多样性

随机每个粒子的颜色,让其不一样。这种办法可能是最粗糙的,勉强算一个办法,但并不实用。

2.运动轨迹多样性

随机每个粒子的运动轨迹和位置,制造出散乱的效果。这种办法尚可,有一些散乱的感觉,还算常见。

3.粒子图形多样性

让每一个粒子都长得不一样。可通过构造随机矩阵来改变每一个粒子的形态,效果比较好,附加位置随机,常见的有花瓣飘散,雪花飘散效果。

五、代码示例

float rand(float n) {
    return fract(sin(n) * 43758.5453123);
}

void main()
{
    vec2 textSize = 1.0/textureSize(uTexture1,0);
    vec4 nColor = texture(uTexture1, vTexPosition1);
    vec2 pos = vTexPosition1 - 0.5;
    pos /= textSize;
    nColor.rgb = vec3(0.0);
    int Scount = 40; //指定时间发射粒子的个数
    float speed = 60; //粒子运动的速度
    float dtime = 1.0; //粒子发射间隔时间
    float delay = 3.5; //粒子生命周期
    float particleSize = 5; //粒子半径大小
    vec3 Viewcolor = vec3(0.0,1.0,1.0);
    float N = floor(vtime/dtime); //根据时间计算发射粒子批数
    for(int i = 0;i <N+1;i++)
    {
        float seed = rand(i+1.0); //不同批数的粒子随机数不一样
        for(int j = 0;j<Scount;j++)
        {
            if(dtime*(vtime/dtime - i) > delay) //计算当前批次粒子生命周期是否结束
                break;
            float rad = speed*(rand(seed*j * 1.8372 + 3.3459)*0.8 + 0.2); //对速度随机
            float a = 2.0*PI*rand(seed*j*2.1312 + 2.8923); //对发射角度随机

            vec2 pdir = vec2(rad * cos(a), rad * sin(a)); //发射方向

            vec2 sparkPos = max(vtime/dtime - i,0.0)*pdir; //偏移距离

            float psize = length(sparkPos - pos); //计算当前位置与发射点的距离(加与减只是方向的区别,由于是圆,都可,不做分辨)
            if(psize< particleSize) //在粒子大小范围内的取色
            {
                vec3 colorR = vec3(rand(seed*j*2.13454),rand(seed*j*1.78345),rand(seed*j*3.26187)); //对粒子颜色随机
                nColor.rgb = smoothstep(0.95,1.05,particleSize/psize) * colorR; //颜色混合
                nColor.rgb = nColor.rgb*smoothstep(delay,0.0,dtime*(vtime/dtime - i)); //根据生命周期变淡
            }
        }

    }
    FragColor = nColor;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值