zoukankan      html  css  js  c++  java
  • shader飞线改进版

    项目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, 0, minx ),
                new THREE.Vector3( minx/2,maxx % 100 + 60, maxx * 2/ 3 ),
                new THREE.Vector3( maxx/2,maxx % 100 + 60, maxx / 3  ),
                new THREE.Vector3( maxx, 0,  maxx)
            );
            var points = curve.getPoints( (maxx - minx) * 5 );
    
            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 = 0;i< 4000;i++){
           var minx = randomNum(-2000,-600)/10;
           var maxx = randomNum(600,2000)/10;
           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

  • 相关阅读:
    Elasticsearch:用户安全设置
    Elasticsearch:significant terms aggregation
    Elastic:Elastic部署架构介绍
    Elasticsearch:Smart Chinese Analysis plugin
    Elasticsearch:ICU分词器介绍
    新版本中的hits.total匹配数说明
    Elasticsearch:fuzzy 搜索 (模糊搜索)
    Elasticsearch:运用search_after来进行深度分页
    Elasticsearch:运用scroll接口对大量数据实现更好的分页
    Elasticsearch:search template
  • 原文地址:https://www.cnblogs.com/eco-just/p/11210816.html
Copyright © 2011-2022 走看看