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;
    };

關於如何往着色器進行傳值有空再講。。。。。。。。。。。。。。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章