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

    技术2022-08-01  76

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

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

    Processed: 0.018, SQL: 9