three.js粒子效果(分别基于CPU&GPU实现)

前段时间做了一个基于CPU和GPU对比的粒子效果丢在学习WebGL的群里,技术上没有多作讲解,有同学反馈看不太懂GPU版本,干脆开一篇文章,重点讲解基于GPU开发的版本。

一、概况

废话不多说,先丢上demo,用移动设备更能明显感觉性能差异。

维护粒子位移颜色尺寸
GPU版本  CPU版本

维护粒子位移
GPU版本  CPU版本

结论:
同时需要维护多种粒子特征变化时,GPU有明显优势。
只是维护粒子位移时,GPU版本稍流畅,但优势并不明显。
当然,这还得具体到设备,一些中低端Android机器,GPU太渣,不如CPU计算。

二、技术实现

three.js中,粒子效果的实现方式大概分为三种:
1、Javascript直接计算粒子的状态变化,即基于CPU实现;
2、Javascript通知顶点着色器粒子的生命周期,由顶点着色器运行,即基于GPU实现;
3、粒子生成与状态维护全部由片元着色器负责,即屏幕特效,同样是基于GPU中实现。
第3种方式本文暂不介绍。

2.1、基于CPU实现

维护位移、颜色、尺寸:
http://tgideas.qq.com/2017/three/shader/particle-gpu/cpu.html维护位移:
http://tgideas.qq.com/2017/three/shader/particle-gpu/gpu-position.html

步骤1&2:
首先加载由三维软件制作的几何体,然后生成粒子系统 。

var material = new THREE.PointsMaterial({size:4, color:0xff0000});
var particleSystem = new THREE.Points(geometry , material);

从代码中可以看出,材质是针对整介粒子系统设置的,所以只能维护粒子位移。
如果要维护粒子颜色、尺寸呢?
我们必须为每个粒子设置不同的材质,由此也造成不小的性能损耗 。
 
步骤3:
使用Tween修改所有顶点位置。

var tween = new TWEEN.Tween(pos).to({val: 0}, 2000).easing(TWEEN.Easing.Quadratic.InOut).delay(1000).onUpdate(callback);
function callback(){
	var val = this.val;
	var particles = particleSystem.geometry.vertices;
	for(var i = 0; i < particles.length; i++) {
		var pos = particles[i];
		pos.x = position1[i].x * val + position2[i].x * (1-val);
		pos.y = position1[i].y * val + position2[i].y * (1-val);
		pos.z = position1[i].z * val + position2[i].z * (1-val);
	}
	particleSystem.geometry.verticesNeedUpdate = true;
}

从代码中可以看出,粒子的状态都是通过Javascript,由CPU来计算。

2.2、基于GPU实现

维护粒子位移、颜色、尺寸:
http://tgideas.qq.com/2017/three/shader/particle-gpu/gpu.html

对比CPU实现流程图,我们会发现,Tween并不直接计算所有顶点位置,而是只通知动画运行时间,由顶点着色器来完成具体运算。
既然运算部分在顶点着色器,那么,需要我们自己书写着色器(opengl es),所以我们选用three.js中的ShaderMaterial。

步骤1:
首先生成粒子系统:

var uniforms = {
	texture:{value: new THREE.TextureLoader().load( "dot.png")},
	val: {value: 1.0}
};
var shaderMaterial = new THREE.ShaderMaterial({
	uniforms:     uniforms,
	vertexShader:   document.getElementById(‘vertexshader‘).textContent,
	fragmentShader: document.getElementById(‘fragmentshader‘).textContent,
	blending:       THREE.AdditiveBlending,
	depthTest:      false,
	transparent:    true
});
particleSystem = new THREE.Points(moreObj, shaderMaterial);

uniforms是连接javascript与着色器的通道。
uniforms.val 即由tween来维护的动画运行值。
vertexShader和fragmentShader,即我们要定义的顶点着色器,和片元着色器,它们负责具体的粒子状态的运算,我们定义在网页中。

步骤2:
定义顶点着色器:

attribute float size; // 粒子尺寸
attribute vec3 position2; // 目标顶点位置
uniform float val; // 动画运行时间
varying vec3 vPos; // 将顶点位置传输给片元着色器

void main() {
    // 计算粒子位置
    vPos.x = position.x * val + position2.x * (1.-val);
    vPos.y = position.y* val + position2.y * (1.-val);
    vPos.z = position.z* val + position2.z * (1.-val);
    // 坐标转换
    vec4 mvPosition = modelViewMatrix * vec4( vPos, 1.0 );
    gl_PointSize = size * ( 300.0 / -mvPosition.z );
    gl_Position = projectionMatrix * mvPosition;

}

three.js内置,自动传递给顶点着色器的变量:
attribute position - 顶点坐标
mat4 modelViewMatrix - 模型+视图矩阵
mat4 projectionMatrix - 投影矩阵

定义片元着色器:

uniform sampler2D texture;
varying vec3 vPos;

void main() {
    // 计算粒子颜色,通过位置
    vec3 vColor = vec3(1.0, 0., 0.);
    vColor.r = vPos.z/50.;
    vColor.g = vPos.y/50.;
    vColor.b = vPos.x/50.;

    gl_FragColor = vec4(vColor, 1.0 );
    // 顶点贴图
    gl_FragColor = gl_FragColor * texture2D( texture, gl_PointCoord );

}

  

步骤3:
负责维护粒子运行时间:

tween = new TWEEN.Tween(pos).to({val: 0}, 2000).onUpdate(callback);
function callback(){
	particleSystem.material.uniforms.val.value = this.val;
}

三、延伸阅读

类THREE.Points做了什么?
其实真没干什么,主要是申明它的type是Points。
当我们执行渲染时,WebGL会绘制Point,即调用gl.drawArrays(gl.POINTS…
而通常,比如type为Mesh时,three.js会调用gl.drawArrays(gl.TRIANGLES…

类THREE.PointsMaterial做了什么?
同样,点材质也是three.js最简单的类之一,相对于基类Material,它多做的事情只是传递了size,即点的尺寸这个值。

时间: 2024-10-09 00:47:40

three.js粒子效果(分别基于CPU&GPU实现)的相关文章

基于HTML5 Canvas粒子效果文字动画特效

之前我们分享过很多超酷的文字特效,其中也有利用HTML5和CSS3的.今天我们要来分享一款基于HTML5 Canvas的文字特效,输入框中输入想要展示的文字,回车后即可在canvas上绘制出粒子效果的文字动画,相当酷的动画效果. 在线预览   源码下载 实现的代码. html代码: <canvas class="canvas"></canvas> <div class="help"> ?</div> <div c

基于HTML5 Canvas生成粒子效果的人物头像

前面我们分享过一个HTML5 Canvas实现的图像马赛克模糊效果,HTML5处理图片真的非常简单.今天我们要再利用HTML5 Canvas实现一个粒子效果的人物头像,你可以任意选择一张头像图片,接下来该图片会被打散成许多粒子,然后慢慢的重组成图片,鼠标滑过图片时粒子还会出现浮动的动画特效,看上去非常酷. 在线预览   源码下载 HTML代码如下 <p class="center">Change pixel resolution <input type="r

html5轻量级炫酷js粒子动画库插件

这是一款基于html5 canvas的轻量级炫酷js粒子动画库插件.该粒子动画库js插件可以设置粒子的形状.旋转.分布.颜色等属性,还可以动态添加粒子,效果非常酷. 同样的例子效果还有:HTML5 Canvas彩色的光粒子模拟粒子运动动画效果. 在线演示:http://www.htmleaf.com/Demo/201501301300.html 下载地址:http://www.htmleaf.com/html5/html5-canvas/201501301299.html

canvas实现的粒子效果

前言:我的这个share很简单,没什么技术水准,主要是我自己觉得canvas这个标签很cool!,简单实用又能装X,而且又能实现很多看起来很炫的东西. 一 关于canvas <canvas>是一个可以使用脚本(通常为JavaScript)在其中绘制图形的 HTML 元素. <canvas> 最早由Apple引入WebKit,用于Mac OS X 的 Dashboard,后来又在Safari和Google Chrome被实现. 基于Gecko 1.8的浏览器,比如 Firefox 1

用仿ActionScript的语法来编写html5——第八篇,图片处理+粒子效果

用仿ActionScript的语法来编写html5系列开发到现在,应该可以做出一些东西了,下面先来研究下图片的各种效果预览各种效果看下图 效果和代码看这里,看不到效果的请下载支持html5的浏览器 http://fsanguo.comoj.com/html5/jstoas07/index.html 2013年3月13日追加 该系列文章写的很早,目前该系列文章中所总结的方法等都已经封装进了lufylegend.js引擎里 lufylegend.js引擎的下载链接 http://lufylegend

简直要逆天!超炫的 HTML5 粒子效果进度条

我喜欢粒子效果作品,特别是那些能够应用于实际的,例如这个由 Jack Rugile 基于 HTML5 Cavnas 编写的进度条效果.看着这么炫的 Loading 效果,即使让我多等一会也无妨:)你呢? 温馨提示:为保证最佳的效果,请在 IE10+.Chrome.Firefox 和 Safari 等现代浏览器中浏览. 插件下载     效果演示 您可能感兴趣的相关文章 Web 开发中很实用的10个效果[附源码下载] 精心挑选的优秀jQuery Ajax分页插件和教程 12个让人惊叹的的创意的 4

SkylineGlobe 如何使用二次开发接口创建粒子效果

SkylineGlobe在6.6版本,ICreator66接口新增加了CreateEffect方法,用来创建粒子效果对象: 以及ITerrainEffect66对象接口,可以灵活设置粒子效果对象的相关属性: 下图是TerraExplorer Pro中对应的菜单界面: 下图是ITerrainEffect66接口的属性: SkylineGlobe提供的示例代码: <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml&qu

JS打字效果的动态菜单代码分享

这篇文章主要介绍了JS打字效果的动态菜单,推荐给大家,有需要的小伙伴可以参考下. 这是一款基于javascript实现的打字效果的动态菜单特效代码,分享给大家学习学习. 小提示:浏览器中如果不能正常运行,可以尝试切换浏览模式.为大家分享的JS打字效果的动态菜单代码如下 <html> <head> <title>JS打字效果的动态菜单</title> <meta http-equiv="imagetoolbar" content=&q

炫彩logo粒子效果

h2{font-size:1.5em}p{text-indent:2em;}前端开发whqet,csdn,王海庆,whqet,前端开发专家 昨天我们学习了利用requestAnimationFrame优化动画控制,然后就忍不住冲动,在fork别人codepen的基础上,实现了这个炫彩logo粒子效果,效果预览如下. -------------------------------------------------------------------------------------------