Cesium对3dtile单个feature进行特效处理

cesium中对3dtile做特效处理的时候,目前只能对所有3dtile处理或者小区域内的3dtile(例如3dtile挖洞,淹没分析等)进行处理,本身上还是对drawcommand进行着色器的部分的改动。通常所作我们只能对选中的featrue进行更改颜色,无法做到更大限度去更改当前选中的feature,本文介绍一种方法对单个feature进行特效处理。

一、原理
通过点击选中场景某个feature,给其赋值一个颜色,将其颜色同时传到着色器中,在片源着色器中读取 tile_featureColor的颜色与传入的颜色做对比,如果两个颜色相同,则对其进行特效处理。若不同则不做任何处理。
Note:为什么选中tile_featureColor与传入的颜色作对比?

                    '    vec2 st = computeSt(' + batchIdAttributeName + '); \n' +
                    '    vec4 featureProperties = texture2D(tile_batchTexture, st); \n' +

上面代码取自于Cesium3DTileBatchTable类的部分着色器,computeSt方法就是根据当前batchId获取当前uv坐标值,通过坐标获取tile_batchTexture对应的颜色,该颜色也就是每一个feature的颜色,通过该颜色与传入的选中颜色值进行对比,然后进行着特效处理。featureProperties 最终会被赋值为tile_featureColor,因此我们可以在着色器中直接取用tile_featureColor的值与传入颜色进行对比。
二、示例
1、feature赋值

       let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
        handler.setInputAction(function (movement) {
            var pickingEntity = viewer.scene.pick(movement.position);
            //判断选择是否为Cesium3DTileFeature
            if (pickingEntity instanceof Cesium.Cesium3DTileFeature) {
                //赋值特征颜色
                pickingEntity.color = new Cesium.Color(1.0,0.0,0.0,1.0);
            }
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

2、颜色传值
同时将new Cesium.Color(1.0,0.0,0.0,1.0)通过uniform传入到着色器
3、着色器处理

    'varying vec3 v_postion;\n'+
    'varying vec3 v_elevationPos;\n'+
    'uniform vec3 u_changeColor; \n' +//为传入的颜色值
    'void main() \n' +
      '{ \n' +
        ' czm_floodanlysis_main();\n'+
        'vec3 test=tile_featureColor.rgb-u_changeColor.rgb;\n'+
        'if((test.r+test.b+test.g)==0.0)\n'+//判断两个颜色是否相同,是否进行特效处理
        '{\n'+
           'gl_FragColor.rgba =vec4(0.0,0.5,1.0,1.0);\n'+
            'float vtxf_a11 = fract(czm_frameNumber / 220.0) * 3.14159265 * 2.0;'+
           ' float vtxf_a12 = v_elevationPos.z / 2000.0 + sin(vtxf_a11) * 0.1;'+
           ' gl_FragColor *= vec4(vtxf_a12, vtxf_a12, vtxf_a12, 1.0);'+
            'float vtxf_a13 = fract(czm_frameNumber / 360.0);'+
            'float vtxf_h = clamp(v_elevationPos.z / 4000.0, 0.0, 1.0);'+
            'vtxf_a13 = abs(vtxf_a13 - 0.5) * 2.0;'+
           ' float vtxf_diff = step(0.005, abs(vtxf_h - vtxf_a13));'+
            'gl_FragColor.rgb += gl_FragColor.rgb * (1.0 - vtxf_diff);\n'+
        '} \n'+
      '}\n';
  return ShaderP

三、在哪里处理着色器?

    ModelUtility.modifyVertexShaderForLogDepth = function(shader, toClipCoordinatesGLSL) {
        shader = ShaderSource.replaceMain(shader, 'czm_depth_main');
        shader +=
            '\n' +
            'void main() \n' +
            '{ \n' +
            '    czm_depth_main(); \n' +
            //在这里处理
            '    czm_vertexLogDepth(' + toClipCoordinatesGLSL + '); \n' +
            '} \n';

        return shader;
    };

关于如何往着色器进行传值有空再讲。。。。。。。。。。。。。。

你可能感兴趣的:(Ceisum)