项目github地址:https://github.com/ecojust/flyline

前面写过一个飞线(基于THREE.Line进行的颜色变化),只是简单地将可视区片元颜色的alpha通道值设为1.0,不在可视区的设为0.0。效果是这样的:

做得很粗糙,而且因为线是没有粗细的,所以效果也不是很理想,后来用pointSize实现线条粗细变化,以及可视区线条颜色的处理,线段头尾点平滑处理等等,所以,改良后的效果如下:

后续又优化了一下代码,用于测试性能(400根线FPS60):

然后不断增加飞线的数量到4000根,FPS依旧能保持在40:

显卡相当于N卡1050的水平,但要比1050差一点。

其实废话了这么多,下面直接上核心代码吧:

    //创建ShaderMaterial纹理的函数
function createMaterial(vertexShader, fragmentShader) {
var vertShader = document.getElementById(vertexShader).innerHTML; //获取顶点着色器的代码
var fragShader = document.getElementById(fragmentShader).innerHTML; //获取片元着色器的代码
//配置着色器里面的attribute变量的值
var attributes = {};
//配置着色器里面的uniform变量的值
var uniforms = {
time: {type: 'f', value: -70.0},
size:{type:'f',value:20.0},
};
var meshMaterial = new THREE.ShaderMaterial({
uniforms: uniforms,
defaultAttributeValues : attributes,
vertexShader: vertShader,
fragmentShader: fragShader,
transparent: true
});
return meshMaterial;
}
    var flylinegroup = [];
function addline(minx,maxx){
var flyline;
var curve = new THREE.CubicBezierCurve3(
new THREE.Vector3( minx, , minx ),
new THREE.Vector3( minx/,maxx % + , maxx * / ),
new THREE.Vector3( maxx/,maxx % + , maxx / ),
new THREE.Vector3( maxx, , maxx)
);
var points = curve.getPoints( (maxx - minx) * ); var geometry = new THREE.Geometry();
geometry.vertices = points;
var material = createMaterial("vertex-shader", "fragment-shader-7");
flyline = new THREE.PointCloud( geometry, material );
flyline.material.uniforms.time.value = minx;
flyline.minx = minx;
flyline.maxx = maxx;
flylinegroup.push(flyline);
scene.add(flyline);
}

贝塞尔曲线上取点,这里简单地根据x轴的长度来决定取点的数量。

<script id="vertex-shader" type="x-shader/x-vertex">
uniform float time;
uniform float size;
varying vec3 iPosition; void main(){
iPosition = vec3(position);
float end = time + size;
float pointsize = 1.0;
if(position.x > time && position.x < end){
pointsize = (position.x - time)/size;
}
gl_PointSize = pointsize * 2.0;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
</script> <script id="fragment-shader-7" type="x-shader/x-fragment">
uniform float time;
uniform float size;
varying vec3 iPosition; void main( void ) {
float end = time + size;
vec4 color;
if(iPosition.x > end || iPosition.x < time){
discard;
}else if(iPosition.x > time && iPosition.x < end){
float ca = fract((iPosition.x - time)/size);
color = vec4(ca/1.9,ca,ca/1.6,1.0);
}
float d = distance(gl_PointCoord, vec2(0.5, 0.5));
if(abs(iPosition.x - end) < 0.2 || abs(iPosition.x - time) < 0.2){
if(d > 0.1){
discard;
}
}
gl_FragColor = color;
}
</script>
for(var i = ;i< ;i++){
var minx = randomNum(-,-)/;
var maxx = randomNum(,)/;
addline(minx,maxx);
}

思路:

1、利用贝塞尔曲线绘制飞线轨迹,并取点(取点数量暂时简单地根据x轴的跨度来算),利用 three.PointCloud 这个类将取得的顶点传给顶点着色器;

2、在顶点着色器中,对于在可视区内的点(position.x值在time和time+size之间)的pointSize进行从左到右依次增大,实现飞线右边粗左边细;

3、在片元着色器中,如果顶点不在可视区那么就discard(不绘制),在可视区内的点从左到右颜色渐变(后期可以通过外部传入的颜色进行渐变处理);

4、在片元着色器中,对于可视区头尾附近的点,进行平滑处理(同理于绘制圆点);

5、随机生成一定范围内的轨迹起始点的x坐标值来生成飞线,for循环来添加n条飞线。

再来一张飞线的近照:

2019.07.26更新

此次添加了自定义飞线渐变色的功能,效果如下,具体代码参照github

shader飞线改进版的更多相关文章

  1. allegro飞线隐藏

    这些都是最基本的操作,你说的应该是飞线的显示和隐藏,命令在display下面,display>show rats>net(component/all) display>blank r ...

  2. echarts做飞线图

    先上图,要不感觉没有说服力: 飞线图应该是大屏中很常见的一种了,通常你可以很轻易的用datav做一个飞线图,而且datav做的大屏逼格真的很高,本身也是开源免费的项目,开箱即用,上手简单……行了回归正 ...

  3. cesium 飞线 瓣体传感器(雷达扫描) 效果

    参考:github地址 本人新手,npm webpack 这些还是一知半解,只记录自己得到成功结果的操作步骤,可能存在多余或错误的步骤. 1.github 把代码下载下来,解压. 2.webstorm ...

  4. svg 飞线,源码

    <html> <head> <meta charset="utf-8" /> <meta name="viewport" ...

  5. altium designer 鼠线

    第一: 按“L”进入View Configurations 要确保Default Color for New Nets是勾上的. 第二: 如果“PCB”的下拉列表处于“From-To Editor”状 ...

  6. JS实现环绕地球飞行的3D飞行线动画效果(JS+HTML)

    1.项目介绍 JS+HTML实现绕地球飞行的3D飞行线动画效果,且3D地球可以随意拖动和滑动缩放,画面中心是蓝色地球,地球表面上的两点连线之间有光电随机出现沿着抛物线轨迹3D飞行,可使用较好的浏览器打 ...

  7. Altium Designer PCB制作入门实例

    概要:本章旨在说明如何生成电路原理图.把设计信息更新到PCB文件中以及在PCB中布线和生成器件输出文件.并且介绍了工程和集成库的概念以及提供了3D PCB开发环境的简要说明.欢迎使用Altium De ...

  8. Cesium参考资源

    Reference resources cesium官网 cesium 下载 cesium官方文档 APIs cesium-workshop github cesium 官方示例 cesium git ...

  9. 使用Three.js实现炫酷的赛博朋克风格3D数字地球大屏 🌐

    声明:本文涉及图文和模型素材仅用于个人学习.研究和欣赏,请勿二次修改.非法传播.转载.出版.商用.及进行其他获利行为. 背景 近期工作有涉及到数字大屏的需求,于是利用业余时间,结合 Three.js ...

随机推荐

  1. 【安徽集训】Emerald

    Description \(n\) 座城市在数轴上,第 \(i\) 座城市有一条连向第 \(i+1\) 座城市的单向边.每座城市有一个类型 A/B 以及一个非负整数人口,A 类城市的人觉得自己的城市比 ...

  2. linux下进程间通信的机制

    今天突然想起了nginx解决惊群的方法,就是在多个进程间利用锁来保证同一时刻只能有一个worker进程在自己的epoll中加入监听的句柄,那么进程间是怎么共享变量的呢,下面就介绍一下共享内存 共享内存 ...

  3. oracle plsql登陆用户名密码都正确,拒绝登陆

    先通过sqlplus  或者 sql developer 或者其他用户登陆 然后更改 登陆不上的用户的密码  然后再用plsql登陆就可以了  然后还可以再把用户密码再改回来 也可以登陆了

  4. TCP_Wrappers访问控制

    一.TCP_Wrappers简介 对有状态连接的特定服务进行安全检测并实现访问控制,它以库文件形式实现,某进程是否接受libwrap的控制取决于发起此进程的程序在编译时是否针对libwrap进行编译的 ...

  5. Java-生成缩略图工具类

    import java.awt.Color; import java.awt.Graphics2D; import java.awt.Image; import java.awt.RenderingH ...

  6. 【Python之路】特别篇--Redis

    NoSQL(NoSQL = Not Only SQL ),意即“不仅仅是SQL”,泛指非关系型的数据库 随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发 ...

  7. ListView如何获取点击单元格内容

    Point m_MBRpt = listView1.PointToClient(Control.MousePosition);            ListViewItem lstrow = lis ...

  8. luoguP3373 【模板】线段树 2

    P3373 [模板]线段树 2 969通过 3.9K提交 题目提供者 HansBug 标签 云端↑ 难度 提高+/省选- 时空限制 1s / 128MB 题目描述 如题,已知一个数列,你需要进行下面两 ...

  9. 深度学习笔记(十四)车道线检测 SCNN

    论文:Spatial As Deep: Spatial CNN for Traffic Scene Understanding 代码:https://github.com/XingangPan/SCN ...

  10. Catch That Cow (POJ - 3278)(简单BFS)

    转载请注明出处:https://blog.csdn.net/Mercury_Lc/article/details/82693928作者:Mercury_Lc 题目链接 题解:给你x.y,x可以加1.减 ...