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

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

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

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

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

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

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

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

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

  1. <script id="vertex-shader" type="x-shader/x-vertex">
  2. uniform float time;
  3. uniform float size;
  4. varying vec3 iPosition;
  5.  
  6. void main(){
  7. iPosition = vec3(position);
  8. float end = time + size;
  9. float pointsize = 1.0;
  10. if(position.x > time && position.x < end){
  11. pointsize = (position.x - time)/size;
  12. }
  13. gl_PointSize = pointsize * 2.0;
  14. gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
  15. }
  16. </script>
  17.  
  18. <script id="fragment-shader-7" type="x-shader/x-fragment">
  19. uniform float time;
  20. uniform float size;
  21. varying vec3 iPosition;
  22.  
  23. void main( void ) {
  24. float end = time + size;
  25. vec4 color;
  26. if(iPosition.x > end || iPosition.x < time){
  27. discard;
  28. }else if(iPosition.x > time && iPosition.x < end){
  29. float ca = fract((iPosition.x - time)/size);
  30. color = vec4(ca/1.9,ca,ca/1.6,1.0);
  31. }
  32. float d = distance(gl_PointCoord, vec2(0.5, 0.5));
  33. if(abs(iPosition.x - end) < 0.2 || abs(iPosition.x - time) < 0.2){
  34. if(d > 0.1){
  35. discard;
  36. }
  37. }
  38. gl_FragColor = color;
  39. }
  40. </script>
  1. for(var i = ;i< ;i++){
  2. var minx = randomNum(-,-)/;
  3. var maxx = randomNum(,)/;
  4. addline(minx,maxx);
  5. }

思路:

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. 【BZOJ 3514】Codechef MARCH14 GERALD07 加强版

    题意 \(n\) 个点 \(m\) 条边的无向图,\(k\) 次询问保留图中编号在 \([l,r]\) 的边的时候图中的联通块个数.强制在线. \(n,m,k\le 2\times 10^5\) 题解 ...

  2. 02 Vue介绍与安装,指令系统 v-*、音乐播放器

    VUE文档 https://cn.vuejs.org/v2/guide/ 1.vue的介绍 尤雨溪 1.vue的优点 2.vue的介绍 3.vue的安装 4.声明式渲染 <body> &l ...

  3. 【51nod 1667】概率好题

    题目 甲乙进行比赛. 他们各有k1,k2个集合[Li,Ri] 每次随机从他们拥有的每个集合中都取出一个数 S1=sigma甲取出的数,S2同理 若S1>S2甲胜 若S1=S2平局 否则乙胜 分别 ...

  4. jQuery.post(url, [data], [callback], [type])

    jQuery.post(url, [data], [callback], [type]) 概述 通过远程 HTTP POST 请求载入信息. 这是一个简单的 POST 请求功能以取代复杂 $.ajax ...

  5. mysql explain 执行计划详解

    1).id列数字越大越先执行,如果说数字一样大,那么就从上往下依次执行,id列为null的就表是这是一个结果集,不需要使用它来进行查询.   2).select_type列常见的有: A:simple ...

  6. CSS3选择器:nth-child和:nth-of-type的差异

    p:nth-child(2)表示这个元素要是p标签,且是第二个子元素,是两个必须满足的条件. <section> <div>我是一个普通的div标签</div> & ...

  7. python3 输入与输出

    pyhon3 io 输入和输出myread=open('E:/路径.txt')#open()会将返回一个file对象mywrite=open('E:/3/路径.txt','w')#后面w是如果文件存在 ...

  8. 线程系列4--Java线程范围内的共享数据(一)

    这张图片是我看传智播客的视频时的截屏,这个图片很直观的展示了线程范围内的数据共享.当同一个线程在执行三个不同业务模块时,这三个业务模块访问的数据是共享的.更直白的说,当一个执行线索在穿个每个业务模块时 ...

  9. Amaple.js框架详细介绍

    Amaple · 体验优先的JavaScript单页框架 Amaple (点此查看Github仓库)是专为单页web应用而设计的基于页面模块化的JavaScript框架,它可使开发者快速开发单页web ...

  10. TCP套接字选项SO_LINGER与TCP_LINGER2

    概述 本文对两个LINGER相关的套接字选项进行源码层面的分析,以更明确其各自的作用和区别: man page SO_LINGER,该选项是socket层面的选项,通过struct linger结构来 ...