cesium天际线分析已经很成熟了,今天分享一个在网上大佬的代码基础上,实现天际线自定义粗细功能(无需修改源码)。
参考文章:
Cesium实战记录(五)天际线分析_cesium天际线分析_Giser_往事随风的博客-CSDN博客
天际线分析的实现原理是边缘检测和结合像元深度信息的着色器处理。在原文中,将内置的边缘检测算法(Cesium.PostProcessStageLibrary.createEdgeDetectionStage())和自定义的两个着色器处理算法相结合(Cesium.PostProcessStageComposite())实现天际线着色。
实现自定义天际线粗细的思路是,将官方定义的边缘检测算法自定义成一个新的着色器算法(new Cesium.PostProcessStage)将官方的glsl代码传给fragmentShader参数。并在glsl中做小的修改。
官方原glsl代码:https://github.com/CesiumGS/cesium/blob/1.86/Source/Shaders/PostProcessStages/EdgeDetection.glslhttps://github.com/CesiumGS/cesium/blob/1.86/Source/Shaders/PostProcessStages/EdgeDetection.glsl修改后的glsl代码(${customWidth}传入自定义宽度)
const edgeFs = `
uniform sampler2D depthTexture;
uniform float length;
uniform vec4 color;
varying vec2 v_textureCoordinates;
void main(void)
{
float directions[3];
directions[0] = -1.0;
directions[1] = 0.0;
directions[2] = 1.0;
float scalars[3];
scalars[0] = 3.0;
scalars[1] = 10.0;
scalars[2] = 3.0;
float czm_pixelRatio_width = float(${customWidth});
float padx = czm_pixelRatio_width / czm_viewport.z;
float pady = czm_pixelRatio_width / czm_viewport.w;
#ifdef CZM_SELECTED_FEATURE
bool selected = false;
for (int i = 0; i < 3; ++i)
{
float dir = directions[i];
selected = selected || czm_selected(vec2(-padx, dir * pady));
selected = selected || czm_selected(vec2(padx, dir * pady));
selected = selected || czm_selected(vec2(dir * padx, -pady));
selected = selected || czm_selected(vec2(dir * padx, pady));
if (selected)
{
break;
}
}
if (!selected)
{
gl_FragColor = vec4(color.rgb, 0.0);
return;
}
#endif
float horizEdge = 0.0;
float vertEdge = 0.0;
for (int i = 0; i < 3; ++i)
{
float dir = directions[i];
float scale = scalars[i];
horizEdge -= texture2D(depthTexture, v_textureCoordinates + vec2(-padx, dir * pady)).x * scale;
horizEdge += texture2D(depthTexture, v_textureCoordinates + vec2(padx, dir * pady)).x * scale;
vertEdge -= texture2D(depthTexture, v_textureCoordinates + vec2(dir * padx, -pady)).x * scale;
vertEdge += texture2D(depthTexture, v_textureCoordinates + vec2(dir * padx, pady)).x * scale;
}
float len = sqrt(horizEdge * horizEdge + vertEdge * vertEdge);
gl_FragColor = vec4(color.rgb, len > length ? color.a : 0.0);
}`
自定义新的边缘检测算法:
const myOwnEdgeDetection = new Cesium.PostProcessStage({
name: 'myEdgeDetection',
fragmentShader: edgeFs,
uniforms: {
length: 0.5,
color: Cesium.Color.BLACK
}
})
然后把他们Composite起来
const silhouette = new Cesium.PostProcessStageComposite({
name: 'czm_skyline',
stages: [myOwnEdgeDetection, postProccessStage, postProccessStage1],
inputPreviousStageTexture: false,
uniforms: myOwnEdgeDetection.uniforms
})
最后将自定义的着色串传到viewer.scene.postProcessStages中就完成了。