查了一堆的资料,最终落位于后处理
https://sandcastle.cesium.com/?src=Post%20Processing.html&label=All
silhouette的效果可以理解为物体轮廓、描边,相当于把物体的外轮廓线勾勒出来
https://sandcastle.cesium.com/?src=Ambient%20Occlusion.html&label=All
简称AO,一般译作环境光遮蔽。
AO是来描绘物体和物体相交或靠近的时候遮挡周围漫反射光线的效果,可以解决或改善漏光、飘和阴影不实等问题,解决或改善场景中缝隙、褶皱与墙角、角线以及细小物体等的表现不清晰问题,综合改善细节尤其是暗部阴影,增强空间的层次感、真实感,同时加强和改善画面明暗对比,增强画面的艺术性。AO简单来说就是根据周围物体对光线的遮挡程度,改变明暗效果。
var ambientOcclusion = viewer.scene.postProcessStages.ambientOcclusion;
ambientOcclusion.enabled = true;
ambientOcclusion.uniforms.ambientOcclusionOnly = false;
ambientOcclusion.uniforms.intensity = 3;
ambientOcclusion.uniforms.bias = 0.1;
ambientOcclusion.uniforms.lengthCap = 0.03;
ambientOcclusion.uniforms.stepSize = 1;
ambientOcclusion.uniforms.blurStepSize = 0.86;
泛光,一个明亮的物体真的有种明亮的感觉。泛光可以极大提升场景中的光照效果,并提供了极大的效果提升
let viewer = new Cesium.Viewer('cesium-container');
viewer.scene.globe.enableLighting = true;// 开启全球光照
viewer.shadows = true
// 亮度设置
var stages = viewer.scene.postProcessStages;
viewer.scene.brightness = viewer.scene.brightness || stages.add(Cesium.PostProcessStageLibrary.createBrightnessStage());
viewer.scene.brightness.enabled = true;
viewer.scene.brightness.uniforms.brightness = Number(2);
var fs =
'uniform sampler2D colorTexture;\n' +
'varying vec2 v_textureCoordinates;\n' +
'uniform float scale;\n' +
'uniform vec3 offset;\n' +
'void main() {\n' +
' vec4 color = texture2D(colorTexture, v_textureCoordinates);\n' + //获取片段颜色
' gl_FragColor = vec4(color.rgb * scale + offset, 10.0);\n' +
'}\n'; //放大片段颜色系数
viewer.scene.postProcessStages.add(new Cesium.PostProcessStage({
fragmentShader: fs,
uniforms: {
scale: 1.1,
offset: function () {
// return new Cesium.Cartesian3(0.1, 0.2, 0.3);
return new Cesium.Cartesian3(0.01, 0.02, 0.03);
}
}
}));
参考文章
cesium中有个属性viewer.resolutionScale,默认值是1.0。
JavaScript中有个属性window.devicePixelRatio,属性返回的是当前显示设备的物理像素分辨率与CSS像素分辨率的比率,即一个CSS像素和一个物理像素的大小比值
cesium中viewer.resolutionScale默认值是1.0,也就是说无论在哪个屏幕上,cesium都把当前显示器的物理像素分辨率与CSS像素分辨率的比率(window.devicePixelRatio)当成是1.0来渲染,而实际上的比率可能是1.0或者1.25或者2.0(比如mac电脑Retina屏),所以造成锯齿和模糊。
//是否开启抗锯齿
if(Cesium.FeatureDetection.supportsImageRenderingPixelated()){//判断是否支持图像渲染像素化处理
viewer.resolutionScale = window.devicePixelRatio;
}
viewer.scene.fxaa = true;
viewer.scene.postProcessStages.fxaa.enabled = true;
this.labelInfo=this.viewer.entities.add(new Cesium.Entity());
this.labelInfo.position=position;
this.labelInfo.label={
show:true,
showBackground:true,
backgroundColor:Cesium.Color.fromCssColorString('#000'),
scale:0.5, //这里非常巧妙的先将字体大小放大一倍在缩小一倍
font:'normal 32px MicroSoft YaHei',
text:`blabla~~`,
pixelOffset :new Cesium.Cartesian2(-120, -100),
horizontalOrigin:Cesium.HorizontalOrigin.LEFT
}
github issue
lightColor : new Cesium.Cartesian3(100.0,100.0, 100.0),表示,rgb的倍数,这样就是白光增强到100倍。对Pbrt材质有效,倾斜摄影不生效。
tileset.lightColor = new Cesium.Cartesian3(1000,1000,1000)
官网示例
不适用于3dtiles
function updateViewModel() {
if (imageryLayers.length > 0) {
var layer = imageryLayers.get(0);
viewModel.brightness = layer.brightness;
viewModel.contrast = layer.contrast;
viewModel.hue = layer.hue;
viewModel.saturation = layer.saturation;
viewModel.gamma = layer.gamma;
}
参考文章
viewer._cesiumWidget._supportsImageRenderingPixelated = Cesium.FeatureDetection.supportsImageRenderingPixelated();
viewer._cesiumWidget._forceResize = true;
if (Cesium.FeatureDetection.supportsImageRenderingPixelated()) {
var vtxf_dpr = window.devicePixelRatio;
// 适度降低分辨率
while (vtxf_dpr >= 2.0) {
vtxf_dpr /= 2.0;
}
//alert(dpr);
viewer.resolutionScale = vtxf_dpr;
}
官方示例
function updatePostProcess() {
var bloom = viewer.scene.postProcessStages.bloom;
bloom.enabled = Boolean(viewModel.show);
bloom.uniforms.glowOnly = Boolean(viewModel.glowOnly);
bloom.uniforms.contrast = Number(viewModel.contrast);
bloom.uniforms.brightness = Number(viewModel.brightness);
bloom.uniforms.delta = Number(viewModel.delta);
bloom.uniforms.sigma = Number(viewModel.sigma);
bloom.uniforms.stepSize = Number(viewModel.stepSize);
}
cesium| PostProcessStage后期处理
Cesium后处理postProcessStages特效
Cesium源码剖析—Post Processing之物体描边(Silhouette)
var collection = viewer.scene.postProcessStages;
var edgeDetection = Cesium.PostProcessStageLibrary.createEdgeDetectionStage();
var postProccessStage = new Cesium.PostProcessStage({
name: 'czm_skylinetemp',
fragmentShader: 'uniform sampler2D colorTexture;' +
'uniform sampler2D depthTexture;' +
'varying vec2 v_textureCoordinates;' +
'void main(void)' +
'{' +
'float depth = czm_readDepth(depthTexture, v_textureCoordinates);' +
'vec4 color = texture2D(colorTexture, v_textureCoordinates);' +
'if(depth<1.0 - 0.000001){'+
'gl_FragColor = color;' +
'}'+
'else{'+
'gl_FragColor = vec4(1.0,0.0,0.0,1.0);'+
'}'+
'}'
});
var postProccessStage1 = new Cesium.PostProcessStage({
name: 'czm_skylinetemp1',
fragmentShader: 'uniform sampler2D colorTexture;' +
'uniform sampler2D redTexture;' +
'uniform sampler2D silhouetteTexture;' +
'varying vec2 v_textureCoordinates;' +
'void main(void)' +
'{' +
'vec4 redcolor=texture2D(redTexture, v_textureCoordinates);'+
'vec4 silhouetteColor = texture2D(silhouetteTexture, v_textureCoordinates);' +
'vec4 color = texture2D(colorTexture, v_textureCoordinates);' +
'if(redcolor.r == 1.0){'+
'gl_FragColor = mix(color, vec4(1.0,0.0,0.0,1.0), silhouetteColor.a);' +
'}'+
'else{'+
'gl_FragColor = color;'+
'}'+
'}',
uniforms: {
redTexture: postProccessStage.name,
silhouetteTexture: edgeDetection.name
}
});
var postProccessStage = new Cesium.PostProcessStageComposite({
name: 'czm_skyline',
stages: [edgeDetection, postProccessStage, postProccessStage1],
inputPreviousStageTexture: false,
uniforms: edgeDetection.uniforms
});
collection.add(postProccessStage);
Cesium.PostProcessStageLibrary.createSilhouetteStage (edgeDetectionStages)
此时边缘检测可作为轮廓函数的options参数,但是也可以省略边缘检测参数,直接调用轮廓函数:
var collection = viewer.scene.postProcessStages;
var silhouette = collection.add(Cesium.PostProcessStageLibrary.createSilhouetteStage());
silhouette.enabled = true;
silhouette.uniforms.color = Cesium.Color.YELLOW;
var bloom = viewer.scene.postProcessStages.bloom;
bloom.enabled = true;
bloom.uniforms.glowOnly = false;
bloom.uniforms.contrast = 128;
bloom.uniforms.brightness = -0.3;
bloom.uniforms.delta = 1;
bloom.uniforms.sigma = 2;
bloom.uniforms.stepSize = 1;
viewer.scene.shadowMap = new Cesium.ShadowMap({
lightCamera: viewer.camera,
context: viewer.scene.context
})
viewer.scene.shadowMap.enabled = true;
viewer.scene.sun.show = true;
scene.sun.glowFactor = 10; //太阳变大
viewer.scene.moon.show = true;
scene.moon.onlySunLighting = true;
viewer.scene.skyBox.show = true;
viewer.scene.skyAtmosphere.show = true;
scene.skyAtmosphere.hueShift = -1; //1
scene.skyAtmosphere.saturationShift = -1 ;//1
scene.skyAtmosphere.brightnessShift = -1; //1
var viewer = new Cesium.Viewer("cesiumContainer");
viewer.scene.skyBox.show = true;
viewer.scene.skyAtmosphere.show = true;
var Rain = `
uniform sampler2D colorTexture;//输入的场景渲染照片
varying vec2 v_textureCoordinates;
float hash(float x){
return fract(sin(x*133.3)*13.13);
}
void main(void){
float time = czm_frameNumber / 60.0;
vec2 resolution = czm_viewport.zw;
vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);
vec3 c=vec3(.6,.7,.8);
float a=-.4;
float si=sin(a),co=cos(a);
uv*=mat2(co,-si,si,co);
uv*=length(uv+vec2(0,4.9))*.3+1.;
float v=1.-sin(hash(floor(uv.x*100.))*2.);
float b=clamp(abs(sin(20.*time*v+uv.y*(5./(2.+v))))-.95,0.,1.)*20.;
c*=v*b; //屏幕上雨的颜色
gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(c,1), 0.5); //将雨和三维场景融合
}`;
Cesium.PostProcessStageLibrary.createRainStage = function() {
var rain= new Cesium.PostProcessStage({
name : 'czm_rain',
fragmentShader : Rain
});
return rain;
};
var collection = viewer.scene.postProcessStages;
var rain= Cesium.PostProcessStageLibrary.createRainStage();
collection.add(rain);
var scene = viewer.scene;
scene.skyAtmosphere.hueShift = -0.8;
scene.skyAtmosphere.saturationShift = -0.7;
scene.skyAtmosphere.brightnessShift = -0.33;
scene.fog.density = 0.001;
scene.fog.minimumBrightness = 0.8;
var viewer = new Cesium.Viewer("cesiumContainer");
viewer.scene.skyBox.show = true;
viewer.scene.skyAtmosphere.show = true;
var Snow = `
uniform sampler2D colorTexture; //输入的场景渲染照片
varying vec2 v_textureCoordinates;
float snow(vec2 uv,float scale)
{
float time = czm_frameNumber / 60.0;
float w=smoothstep(1.,0.,-uv.y*(scale/10.));if(w<.1)return 0.;
uv+=time/scale;uv.y+=time*2./scale;uv.x+=sin(uv.y+time*.5)/scale;
uv*=scale;vec2 s=floor(uv),f=fract(uv),p;float k=3.,d;
p=.5+.35*sin(11.*fract(sin((s+p+scale)*mat2(7,3,6,5))*5.))-f;d=length(p);k=min(d,k);
k=smoothstep(0.,k,sin(f.x+f.y)*0.01);
return k*w;
}
void main(void){
vec2 resolution = czm_viewport.zw;
vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y);
vec3 finalColor=vec3(0);
//float c=smoothstep(1.,0.3,clamp(uv.y*.3+.8,0.,.75));
float c = 0.0;
c+=snow(uv,30.)*.0;
c+=snow(uv,20.)*.0;
c+=snow(uv,15.)*.0;
c+=snow(uv,10.);
c+=snow(uv,8.);
c+=snow(uv,6.);
c+=snow(uv,5.);
finalColor=(vec3(c)); //屏幕上雪的颜色
gl_FragColor = mix(texture2D(colorTexture, v_textureCoordinates), vec4(finalColor,1), 0.5); //将雪和三维场景融合
}
`;
Cesium.PostProcessStageLibrary.createSnowStage = function() {
var snow = new Cesium.PostProcessStage({
name : 'czm_snow',
fragmentShader : Snow
});
return snow;
};
var collection = viewer.scene.postProcessStages;
var snow = Cesium.PostProcessStageLibrary.createSnowStage();
collection.add(snow);
scene.fog.enabled = true;
scene.fog.density = 0.001;
scene.fog.minimumBrightness = 0.8;
this.FogStage=new Cesium.PostProcessStage({
"name":"czm_fog",
fragmentShader:" uniform sampler2D colorTexture;\n" +
" uniform sampler2D depthTexture;\n" +
" varying vec2 v_textureCoordinates;\n" +
" void main(void)\n" +
" {\n" +
" vec4 origcolor=texture2D(colorTexture, v_textureCoordinates);\n" +
" vec4 fogcolor=vec4(0.8,0.8,0.8,0.5);\n" +
"\n" +
" float depth = czm_readDepth(depthTexture, v_textureCoordinates);\n" +
" vec4 depthcolor=texture2D(depthTexture, v_textureCoordinates);\n" +
"\n" +
" float f=(depthcolor.r-0.22)/0.8;\n" +
" if(f<0.0) f=0.0;\n" +
" else if(f>1.0) f=1.0;\n" +
" gl_FragColor = mix(origcolor,fogcolor,f);\n" +
" }"
});
this.viewer.scene.postProcessStages.add(this.FogStage);
this.FogStage.enabled=true;
var collection = viewer.scene.postProcessStages;
var silhouette = collection.add(Cesium.PostProcessStageLibrary.createBlackAndWhiteStage ());
silhouette.enabled = true;
silhouette.uniforms.gradations =15.0; 调节黑白程度(1-20)
var collection = viewer.scene.postProcessStages;
var silhouette = collection.add(Cesium.PostProcessStageLibrary.createBlurStage());
silhouette.enabled = true;
silhouette.uniforms.delta=1.0;
silhouette.uniforms.sigma=1.0;
silhouette.uniforms.stepSize=20.0;(行之有效)
var collection = viewer.scene.postProcessStages;
var silhouette = collection.add(Cesium.PostProcessStageLibrary.createBrightnessStage());
silhouette.enabled = true;
silhouette.uniforms.brightness=0.1; (调节亮度0-3最佳)
var collection = viewer.scene.postProcessStages;
var silhouette = collection.add(Cesium.PostProcessStageLibrary.createDepthOfFieldStage());
silhouette.enabled = true;
silhouette.uniforms.focalDistance=1; (1000)
silhouette.uniforms.delta=1; (5)
silhouette.uniforms.sigma=1; (5)
silhouette.uniforms.stepSize=1; (10)
var viewer = new Cesium.Viewer("cesiumContainer");
var lensFlare = viewer.scene.postProcessStages.add(
Cesium.PostProcessStageLibrary.createLensFlareStage()
);
function updatePostProcess() {
lensFlare.enabled = 5;
lensFlare.uniforms.intensity = 5;
lensFlare.uniforms.distortion = 5;
lensFlare.uniforms.ghostDispersal =5;
lensFlare.uniforms.haloWidth = 5;
lensFlare.uniforms.dirtAmount =5;
lensFlare.uniforms.earthRadius = 5;
}
updatePostProcess();
var camera = viewer.scene.camera;
camera.position = new Cesium.Cartesian3(
40010447.97500168,
56238683.46406788,
20776576.752223067
);
camera.direction = new Cesium.Cartesian3(
-0.5549701431494752,
-0.7801872010801355,
-0.2886452346452218
);
camera.up = new Cesium.Cartesian3(
-0.3016252360948521,
-0.13464820558887716,
0.9438707950150912
);
camera.right = Cesium.Cartesian3.cross(
camera.direction,
camera.up,
new Cesium.Cartesian3()
);
viewer.clock.currentTime = new Cesium.JulianDate(
2458047,
27399.860215000022
);
var collection = viewer.scene.postProcessStages;
var silhouette = collection.add(Cesium.PostProcessStageLibrary.createNightVisionStage());
silhouette.enabled = true;
var viewer = new Cesium.Viewer("cesiumContainer");
var silhouette = Cesium.PostProcessStageLibrary.createAmbientOcclusionStage();
silhouette.enabled = true;
silhouette.uniforms.intensity = 5.0;
silhouette.uniforms.bias = 15.0;
silhouette.uniforms.lengthCap = 5.0;
silhouette.uniforms.stepSize = 5.0;
silhouette.uniforms.frustumLength = 5.0;
viewer.scene.shadowMap = new Cesium.ShadowMap({
lightCamera:viewer.camera,
context: viewer.scene.context
});
viewer.scene.shadowMap.enabled = true ;