CustomShader

new Cesium.CustomShader(options)

自定义着色器对象,允许自定义M3D缓存图层的顶点着色器和片元着色器代码
Name Type Description
options Object optional 初始化参数
Name Type Default Description
uniforms Array {} optional 传入的uniform变量,类型必须为Cesium.WebGLConstants里的类型, 建议如果是非纹理类型的数据不要使用uniform变量传入,因为uniform变量必须在模型加载时赋值,后面无法修改,如果是想要实时变化, 可以在shader里面实时赋值;注意这里说的uniform变量必须在模型加载时赋值是因为,uniform变量是随着顶点传入webgl中的, 如果要修改必须将模型重新加载,并将数据传入webgl,使用这种方式会导致性能会下降很多;
varyings Array {} optional 传入的varying变量
vertexShaderText String '' optional 传入的顶点着色器代码,必须重写fragmentMain方法
fragmentShaderText String '' optional 传入的片元着色器代码,必须重写vertexMain方法
Example:
-------------使用viewer.scene.layers.appendM3DLayer添加图层---------------------------
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/2.0/武汉建筑轮廓白/武汉建筑轮廓白.mcj';
index = viewer.scene.layers.appendM3DLayer(url, {
    //设置自定义着色器
    customShader: new Cesium.CustomShader({})
});
-------------使用viewer.scene.layers.appendSceneLayer添加图层---------------------------
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/1.0/ZondyFaceModels/ZondyFaceModels.mcj';
index = viewer.scene.layers.appendSceneLayer(url, {
    //设置自定义着色器
    customShader: new Cesium.CustomShader({})
})
-------------当数据被切块时,在callback函数中实时更新shader---------------------------
//M3DServer服务
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/1.0/ZondyFaceModels/ZondyFaceModels.mcj';
index = viewer.scene.layers.appendM3DLayer(url, {
    //在callback中更新shader
    callback: function() {
        //根据index获取M3D对象
        var tileSet = viewer.scene.layers.getM3DLayer(index);
        //确保对象存在
        if(tileSet) {
             //更新你的shader
             tileSet.customShader = new Cesium.CustomShader({})
        }
    }
});
//SceneServer服务或G3DServer服务
var tileSet;
viewer.scene.layers.appendSceneLayer('http://webclient.smaryun.com:8089/igs/rest/g3d/Scene:DaYanTa-M3D', {
    //在loaded中获取M3D对像
    loaded: function (layer) {
        layerScene = layer;
    },
    //在callback中更新shader
    callback: function() {
        //确保对象存在
        if(layerScene) {
            //更新你的shader
            layerScene.customShader = new Cesium.CustomShader({});
        }
     }
});
-------------传入uniform变量---------------------------
//加载M3D模型
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/1.0/ZondyFaceModels/ZondyFaceModels.mcj';
//必须在模型初始化时,给uniform变量赋值
index = viewer.scene.layers.appendM3DLayer(url, {
    //设置自定义着色器
    customShader: new Cesium.CustomShader({
        //传入uniform变量
        uniforms: {
            //第一个变量
            u_uniform1: {
                //类型,必须为Cesium.WebGLConstants里的类型
                type: Cesium.WebGLConstants.FLOAT,
                //值
                value: -100.0
            },
            //第二个变量
            u_uniform2: {
                //类型,必须为Cesium.WebGLConstants里的类型
                type: Cesium.WebGLConstants.FLOAT,
                //值
                value: -100.0
            }
        }
    })
});
-------------传入varying变量,并在顶点和片元着色器中使用---------------------------
//加载M3D模型
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/1.0/ZondyFaceModels/ZondyFaceModels.mcj';
index = viewer.scene.layers.appendM3DLayer(url, {
     //设置自定义着色器
     customShader: new Cesium.CustomShader({
         //传入varying变量
         varyings: {
             //设置一个变量,注意varying变量仅用于顶点着色器像片元着色器传值,因此没有初始值
             u_test: {
                 //类型,必须为Cesium.WebGLConstants里的类型
                 type: Cesium.WebGLConstants.FLOAT
             }
         },
         //顶点着色器代码
         vertexShaderText:
         //在顶点着色器中,将当前顶点的y值赋给u_test
         'void vertexMain(float frameNumber, vec4 oid, inout vec4 position){\n' +
         '  u_test = position.y;\n' +
         '}\n',
         //片元着色器代码
         fragmentShaderText:
         //在片元着色器中,使用u_test的值
         'void fragmentMain(vec4 position, float frameNumber, vec4 oid, inout vec4 fragColor){\n' +
         //设置渐变颜色
         '   vec4 gradiantColor = vec4(0.0, 0.0, 1.0, 0.0);\n' +
         //获取当前顶点高度,注意这里的高度是相对于模型原点的,具体高度范围请从外包盒中获取
         //该模型地下有34米,为方便计算,抬高34米
         //在这里使用了varying变量
         '   float currentHeight = u_test + 34.0;\n' +
         //颜色从140到0进行渐变
         '   if(currentHeight > 0.0) {\n' +
         '       gradiantColor *= currentHeight / 140.0;\n' +
         //注意改变颜色是加法/减法,改变亮度是乘法
         '       fragColor += gradiantColor;\n' +
         '   }\n' +
         '}\n'
     })
});
-------------传入顶点着色器代码---------------------------
//加载M3D模型
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/1.0/ZondyFaceModels/ZondyFaceModels.mcj';
index = viewer.scene.layers.appendM3DLayer(url, {
    //设置自定义着色器
    customShader: new Cesium.CustomShader({
         //顶点着色器代码
         vertexShaderText:
         //参考1.87以上版本写法,必须重写vertexMain方法
         //frameNumber:帧时间,顶点的oid,position:顶点坐标
         'void vertexMain(float frameNumber, vec4 oid, inout vec4 position){\n' +
          //如果高度超过0米,抬高100米
          '  if(position.y > 0.0) {\n' +
          //抬高100米
          '    position.y += 100.0;\n' +
          '  }\n' +
         '}\n'
    })
});
-------------传入片元着色器代码---------------------------
//加载M3D模型
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/1.0/ZondyFaceModels/ZondyFaceModels.mcj';
index = viewer.scene.layers.appendM3DLayer(url, {
    //设置自定义着色器
    customShader: new Cesium.CustomShader({
         //设置片元着色器代码
         fragmentShaderText:
         //参考1.87以上版本写法,必须重写fragmentMain方法
         //position:顶点坐标,frameNumber:帧时间,顶点的oid,fragColor:顶点颜色
         'void fragmentMain(vec4 position, float frameNumber, vec4 oid, inout vec4 fragColor){\n' +
         //给一个蓝色的覆盖物颜色
         '  fragColor += vec4(0.0, 0.0, 0.3, 0.0);\n' +
         '}\n',
    })
});
-------------动态修改着色器---------------------------
//添加M3D数据
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/1.0/ZondyFaceModels/ZondyFaceModels.mcj';
//在初始化时,传入uniform变量
index = viewer.scene.layers.appendM3DLayer(url, {
    duration: 1,
    customShader: new Cesium.CustomShader({
        uniforms: {
            u_testHeight: {
                type: Cesium.WebGLConstants.FLOAT,
                value: -100.0
            }
        }
    })
});
//获取M3D对象
var tileSet = viewer.scene.layers.getM3DLayer(index);
//动态修改片元着色器
tileSet.customShader = new Cesium.CustomShader({
   fragmentShaderText:
   //参考1.87以上版本写法,必须重写fragmentMain方法
   //position:顶点坐标,frameNumber:帧时间,顶点的oid,fragColor:顶点颜色
   'void fragmentMain(vec4 position, float frameNumber, vec4 oid, inout vec4 fragColor){\n' +
    //给一个蓝色的覆盖物颜色
     '  fragColor += vec4(0.0, 0.0, 0.3, 0.0);\n' +
   '}\n'
});
//动态修顶点着色器
tileSet.customShader = new Cesium.CustomShader({
    //顶点着色器代码
    vertexShaderText:
    //参考1.87以上版本写法,必须重写vertexMain方法
    //frameNumber:帧时间,顶点的oid,position:顶点坐标
    'void vertexMain(float frameNumber, vec4 oid, inout vec4 position){\n' +
    //抬高100米
    'position.y += 100.0;\n' +
    '}\n'
});
-------------按高度进行颜色渐变---------------------------
//加载M3D模型
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/1.0/ZondyFaceModels/ZondyFaceModels.mcj';
index = viewer.scene.layers.appendM3DLayer(url, {
    //设置自定义着色器
    customShader: new Cesium.CustomShader({
         fragmentShaderText:
         //参考1.87以上版本写法,必须重写fragmentMain方法
         //position:顶点坐标,frameNumber:帧时间,顶点的oid,fragColor:顶点颜色
         'void fragmentMain(vec4 position, float frameNumber, vec4 oid, inout vec4 fragColor){\n' +
         //设置渐变颜色
         '   vec4 gradiantColor = vec4(0.0, 0.0, 1.0, 0.0);\n' +
         //获取当前顶点高度,注意这里的高度是相对于模型原点的,具体高度范围,请从模型的外包盒中获取
         //此处的最大高度为110,也是从外包盒里获取的
         '   float maxHeight = 110.0;\n' +
          //颜色从maxHeight到0进行渐变
          '   if(position.y > 0.0) {\n' +
          '       gradiantColor *= position.y / maxHeight;\n' +
         //注意改变颜色是加法/减法,改变亮度是乘法
         '       fragColor += gradiantColor;\n' +
         '   }\n' +
         '}\n'
    })
});
-------------呼吸灯效果---------------------------
//加载M3D模型
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/1.0/ZondyFaceModels/ZondyFaceModels.mcj';
index = viewer.scene.layers.appendM3DLayer(url, {
    //设置自定义着色器
    customShader: new Cesium.CustomShader({
         fragmentShaderText:
         //参考1.87以上版本写法,必须重写fragmentMain方法
         //position:顶点坐标,frameNumber:帧时间,顶点的oid,fragColor:顶点颜色
         'void fragmentMain(vec4 position, float frameNumber, vec4 oid, inout vec4 fragColor){\n' +
         //根据当前帧时间(czm_frameNumber)获取周期变化的亮度值,fract即webgl里面的取小数函数
         '   float currentLight = fract(frameNumber / 120.0) * 3.14159265;\n' +
         //根据亮度和高度过去呼吸灯颜色
         '   float breathLampColor = position.y / 320.0 / 2.0 + sin(currentLight) * 0.1;\n' +
         //修改当前颜色
         '   fragColor += vec4(51.0 / 255.0 * breathLampColor, 153.0 / 255.0 * breathLampColor, breathLampColor, 0.0);\n' +
         '}\n'
    })
});
-------------光圈效果---------------------------
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/1.0/ZondyFaceModels/ZondyFaceModels.mcj';
index = viewer.scene.layers.appendM3DLayer(url, {
    //设置自定义着色器
    customShader: new Cesium.CustomShader({
         fragmentShaderText:
         //参考1.87以上版本写法,必须重写fragmentMain方法
         //position:顶点坐标,frameNumber:帧时间,顶点的oid,fragColor:顶点颜色
         'void fragmentMain(vec4 position, float frameNumber, vec4 oid, inout vec4 fragColor){\n' +
         //获取当前顶点高度,注意这里的高度是相对于模型原点的,具体高度范围,请从模型的外包盒中获取
         //此处的最大高度为110米,最小高度为-34米,也是从外包盒里获取的
         '   float currentHeight = position.y + 34.0;\n' +
         //根据当前帧时间(czm_frameNumber),获取当前顶点所处的周期
         '   float time = fract(frameNumber / 360.0);\n' +
         //获取当前高度占整体高度的百分比,0到1之间的值
         //clamp参考https://learn.microsoft.com/zh-cn/previous-versions/hh308289(v=vs.120)
         '   currentHeight = clamp(currentHeight / (110.0 + 34.0), 0.0, 1.0);\n' +
         //处理周期
         '   time = abs(time - 0.5) * 2.0;\n' +
         //根据高度和周期计算光圈
         '   float circle = step(0.005, abs(currentHeight - time));\n' +
         //更新颜色
         '   fragColor.rgb += fragColor.rgb * (1.0 - circle);\n' +
         '}\n'
    })
});
-------------渐变+光圈+高亮---------------------------
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D/2.0/武汉建筑轮廓白/武汉建筑轮廓白.mcj';
index = viewer.scene.layers.appendM3DLayer(url, {
    //设置自定义着色器
    customShader: new Cesium.CustomShader({
         fragmentShaderText:
         //参考1.87以上版本写法,必须重写fragmentMain方法
         //position:顶点坐标,frameNumber:帧时间,顶点的oid,fragColor:顶点颜色
         'void fragmentMain(vec4 position, float frameNumber, vec4 oid, inout vec4 fragColor){\n' +
         //获取当前顶点高度,注意这里的高度是相对于模型原点的,具体高度范围,请从模型的外包盒中获取
         //这份数据最低点距离制图原点有180米,最高点离原点有140米,因此加上180,使最小值为0
         '   float currentHeight = position.y + 180.0;\n' +
         //更新渐变颜色
         '   fragColor += vec4(51.0 / 255.0, 153.0 / 255.0, 1.0, 1.0) * currentHeight / 320.0;\n' +
         //高度在260到320之间,增加高亮
         '   if(currentHeight > 260.0) {\n' +
         '       fragColor *= 1.0 + 0.75 * (currentHeight - 260.0) / 60.0;\n' +
         '   }\n' +
         //根据当前帧时间(czm_frameNumber),获取当前顶点所处的周期
         '   float time = fract(frameNumber / 360.0);\n' +
         //获取当前高度占整体高度的百分比,0到1之间的值
         //clamp参考https://learn.microsoft.com/zh-cn/previous-versions/hh308289(v=vs.120)
         '   currentHeight = clamp(currentHeight / 320.0, 0.0, 1.0);\n' +
         //处理周期
         '   time = abs(time - 0.5) * 2.0;\n' +
         //根据高度和周期计算光圈
         '   float circle = step(0.005, abs(currentHeight - time));\n' +
         //更新颜色
         '   fragColor.rgb += fragColor .rgb * (1.0 - circle);\n' +
         '}\n'
    })
});
-------------通过OID进行高亮---------------------------
//注意必须是M3D2.0数据,且带有OID
var url = 'http://192.168.82.89:8200/3DData/ModelCache/M3D//2.0/M3DAttributeTest_BIN/zondy.mcj';
//指定一个OID,并将其转为颜色
var id = Cesium.Color.fromRgba(511);
//拼装相关shader代码,数值为float类型
var OIDToColor = "";
if(id.red.toString().indexOf('.') < 0) {
    OIDToColor += id.red + '.0';
}else {
    OIDToColor += id.red;
}
OIDToColor += ',';
if(id.green.toString().indexOf('.') < 0) {
    OIDToColor += id.green + '.0';
}else {
    OIDToColor += id.green;
}
OIDToColor += ',';
if(id.blue.toString().indexOf('.') < 0) {
    OIDToColor += id.blue + '.0';
}else {
    OIDToColor += id.blue;
}
OIDToColor += ',';
if(id.alpha.toString().indexOf('.') < 0) {
    OIDToColor += id.alpha + '.0';
}else {
    OIDToColor += id.alpha;
}
index = viewer.scene.layers.appendM3DLayer(url, {
    //设置自定义着色器
    customShader: new Cesium.CustomShader({
         fragmentShaderText:
         //参考1.87以上版本写法,必须重写fragmentMain方法
         //position:顶点坐标,frameNumber:帧时间,顶点的oid,fragColor:顶点颜色
          'void fragmentMain(vec4 position, float frameNumber, vec4 oid, inout vec4 fragColor){\n' +
         //设置外部传入的OID
         '   vec4 outOID = vec4(' + OIDToColor + ');\n' +
         //与当前OID相减
         '   vec4 oidResult =  oid.rgba - outOID.rgba; \n' +
         //相减后的rgba值小于0.0039(相当于1/255),就认为是一样的id
         '   if(abs(oidResult).r < 0.0039 && abs(oidResult).g < 0.0039 && abs(oidResult).b < 0.0039 && abs(oidResult).a < 0.0039){' +
         //oid相同,改变颜色
         '       fragColor.r += 1.0;' +
         '   }' +
         '}\n'
    })
});