@geoblocks/cesium-post-process 0.0.0-stage → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +29 -0
- package/README.md +235 -2
- package/analog-video.js +138 -0
- package/blur.js +39 -0
- package/cesium-post-process.js +23 -0
- package/cloud-cover.js +49 -0
- package/cloud-map.js +122 -0
- package/cloud-noise.js +229 -0
- package/clouds.js +684 -0
- package/color-isolation.js +69 -0
- package/depth-test.js +37 -0
- package/digital-video.js +108 -0
- package/drone-display.js +170 -0
- package/effect.js +64 -0
- package/focus.js +25 -0
- package/frame-clock.js +61 -0
- package/height.js +23 -0
- package/infrared.js +40 -0
- package/jello.js +146 -0
- package/lens-distortion.js +68 -0
- package/lightning.js +321 -0
- package/motion-blur.js +117 -0
- package/package.json +55 -4
- package/precipitation.js +493 -0
- package/shaders/Alpenglow.js +2 -0
- package/shaders/AnalogVideo.js +2 -0
- package/shaders/Beam.js +2 -0
- package/shaders/CloudsBlur.js +2 -0
- package/shaders/CloudsComposite.js +2 -0
- package/shaders/CloudsDensity.js +2 -0
- package/shaders/CloudsDepth.js +2 -0
- package/shaders/CloudsMarch.js +2 -0
- package/shaders/CloudsResolve.js +2 -0
- package/shaders/CloudsShadow.js +2 -0
- package/shaders/CloudsShadowMap.js +2 -0
- package/shaders/CloudsSlab.js +2 -0
- package/shaders/ColorIsolation.js +2 -0
- package/shaders/DepthEdges.js +2 -0
- package/shaders/DigitalVideo.js +2 -0
- package/shaders/DroneDisplay.js +2 -0
- package/shaders/EyeFromDepth.js +2 -0
- package/shaders/Filmic.js +2 -0
- package/shaders/Flashlight.js +2 -0
- package/shaders/Fog.js +2 -0
- package/shaders/Frame.js +2 -0
- package/shaders/Hash.js +2 -0
- package/shaders/Height.js +2 -0
- package/shaders/Hsl.js +2 -0
- package/shaders/Infrared.js +2 -0
- package/shaders/Jello.js +2 -0
- package/shaders/LensDistortion.js +2 -0
- package/shaders/Lightning.js +2 -0
- package/shaders/MotionBlur.js +2 -0
- package/shaders/MotionBlurVelocity.js +2 -0
- package/shaders/Noise.js +2 -0
- package/shaders/Normal.js +2 -0
- package/shaders/Phase.js +2 -0
- package/shaders/Precipitation.js +2 -0
- package/shaders/PrecipitationShaftBlur.js +2 -0
- package/shaders/PrecipitationShafts.js +2 -0
- package/shaders/PrecipitationWind.js +2 -0
- package/shaders/RainHaze.js +2 -0
- package/shaders/Shockwave.js +2 -0
- package/shaders/SkyTable.js +2 -0
- package/shaders/SnowLine.js +2 -0
- package/shaders/SpeedLines.js +2 -0
- package/shaders/Spotlight.js +2 -0
- package/shaders/SpotlightBeam.js +2 -0
- package/shaders/SpotlightBeamBlur.js +2 -0
- package/shaders/SpotlightCone.js +2 -0
- package/shaders/Super8.js +2 -0
- package/shaders/Technicolor.js +2 -0
- package/shaders/TiltShift.js +2 -0
- package/shaders/Toy.js +2 -0
- package/shaders/Trails.js +2 -0
- package/shaders/ValleyFog.js +2 -0
- package/shaders/WeatherMap.js +2 -0
- package/shaders/WhiteModel.js +2 -0
- package/snow-line.js +108 -0
- package/speed-lines.js +71 -0
- package/spotlight.js +193 -0
- package/strikes.js +30 -0
- package/super8.js +164 -0
- package/technicolor.js +56 -0
- package/tilt-shift.js +124 -0
- package/toy.js +192 -0
- package/valley-fog.js +105 -0
- package/weather-map.js +290 -0
- package/white-model.js +105 -0
package/snow-line.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import {Math as CesiumMath} from '@cesium/core';
|
|
2
|
+
import {PostProcessStage} from '@cesium/engine';
|
|
3
|
+
import {acquireTerrainDepth, releaseTerrainDepth} from './depth-test.js';
|
|
4
|
+
import Effect from './effect.js';
|
|
5
|
+
import {heightUniforms} from './height.js';
|
|
6
|
+
import EyeFromDepth from './shaders/EyeFromDepth.js';
|
|
7
|
+
import Height from './shaders/Height.js';
|
|
8
|
+
import Normal from './shaders/Normal.js';
|
|
9
|
+
import SnowLineShader from './shaders/SnowLine.js';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Snow above an altitude, on the slopes gentle enough to hold it, shaded by
|
|
13
|
+
* the sun.
|
|
14
|
+
*/
|
|
15
|
+
export default class SnowLine extends Effect {
|
|
16
|
+
/**
|
|
17
|
+
* @param {import('@cesium/engine').CesiumWidget} viewer
|
|
18
|
+
* @param {{altitude?: number, transition?: number, maxSlope?: number, coverage?: number}} [options]
|
|
19
|
+
*/
|
|
20
|
+
constructor(viewer, options = {}) {
|
|
21
|
+
super(viewer);
|
|
22
|
+
this.altitude_ = options.altitude ?? 2000;
|
|
23
|
+
this.transition_ = options.transition ?? 200;
|
|
24
|
+
this.maxSlope_ = options.maxSlope ?? 50;
|
|
25
|
+
this.coverage_ = options.coverage ?? 1;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @override
|
|
30
|
+
* @param {import('@cesium/engine').Scene} scene
|
|
31
|
+
*/
|
|
32
|
+
createStage_(scene) {
|
|
33
|
+
return new PostProcessStage({
|
|
34
|
+
fragmentShader: EyeFromDepth + Height + Normal + SnowLineShader,
|
|
35
|
+
uniforms: {
|
|
36
|
+
...heightUniforms(scene),
|
|
37
|
+
altitude: () => this.altitude_,
|
|
38
|
+
transition: () => this.transition_,
|
|
39
|
+
maxSlope: () => CesiumMath.toRadians(this.maxSlope_),
|
|
40
|
+
coverage: () => this.coverage_,
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* @override
|
|
47
|
+
* @param {import('@cesium/engine').Scene} scene
|
|
48
|
+
*/
|
|
49
|
+
activated_(scene) {
|
|
50
|
+
acquireTerrainDepth(scene);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* @override
|
|
55
|
+
* @param {import('@cesium/engine').Scene} scene
|
|
56
|
+
*/
|
|
57
|
+
deactivating_(scene) {
|
|
58
|
+
releaseTerrainDepth(scene);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Altitude of the snow line, in meters above the ellipsoid.
|
|
63
|
+
*/
|
|
64
|
+
get altitude() {
|
|
65
|
+
return this.altitude_;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
set altitude(value) {
|
|
69
|
+
this.altitude_ = value;
|
|
70
|
+
this.viewer.scene.requestRender();
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Height of the band around the altitude over which the snow thins out, in meters.
|
|
75
|
+
*/
|
|
76
|
+
get transition() {
|
|
77
|
+
return this.transition_;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
set transition(value) {
|
|
81
|
+
this.transition_ = value;
|
|
82
|
+
this.viewer.scene.requestRender();
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Steepest slope that holds snow, in degrees.
|
|
87
|
+
*/
|
|
88
|
+
get maxSlope() {
|
|
89
|
+
return this.maxSlope_;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
set maxSlope(value) {
|
|
93
|
+
this.maxSlope_ = value;
|
|
94
|
+
this.viewer.scene.requestRender();
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Opacity of the snow, 0 to 1.
|
|
99
|
+
*/
|
|
100
|
+
get coverage() {
|
|
101
|
+
return this.coverage_;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
set coverage(value) {
|
|
105
|
+
this.coverage_ = value;
|
|
106
|
+
this.viewer.scene.requestRender();
|
|
107
|
+
}
|
|
108
|
+
}
|
package/speed-lines.js
ADDED
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import {Cartesian4} from '@cesium/core';
|
|
2
|
+
import {PostProcessStage} from '@cesium/engine';
|
|
3
|
+
import Effect from './effect.js';
|
|
4
|
+
import {eyeFocus} from './focus.js';
|
|
5
|
+
import Hash from './shaders/Hash.js';
|
|
6
|
+
import SpeedLinesShader from './shaders/SpeedLines.js';
|
|
7
|
+
|
|
8
|
+
const focusScratch = new Cartesian4();
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Speed lines: a zoom blur toward the focus and streaks radiating from it.
|
|
12
|
+
* The streaks change with each frame the scene renders, and do not render it
|
|
13
|
+
* by themselves.
|
|
14
|
+
*/
|
|
15
|
+
export default class SpeedLines extends Effect {
|
|
16
|
+
/**
|
|
17
|
+
* @param {import('@cesium/engine').CesiumWidget} viewer
|
|
18
|
+
* @param {{focus?: import('./focus.js').Focus, strength?: number}} [options]
|
|
19
|
+
*/
|
|
20
|
+
constructor(viewer, options = {}) {
|
|
21
|
+
super(viewer);
|
|
22
|
+
this.focus_ = options.focus;
|
|
23
|
+
this.strength_ = options.strength ?? 1;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* @override
|
|
28
|
+
* @param {import('@cesium/engine').Scene} scene
|
|
29
|
+
*/
|
|
30
|
+
createStage_(scene) {
|
|
31
|
+
const stage = new PostProcessStage({
|
|
32
|
+
fragmentShader: Hash + SpeedLinesShader,
|
|
33
|
+
uniforms: {
|
|
34
|
+
focus: () => eyeFocus(scene, this.focus_, focusScratch),
|
|
35
|
+
strength: () => this.strength_,
|
|
36
|
+
time: () => performance.now() / 1000,
|
|
37
|
+
},
|
|
38
|
+
});
|
|
39
|
+
// no pass at all without strength
|
|
40
|
+
stage.enabled = this.strength_ > 0;
|
|
41
|
+
return stage;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* What the lines converge on: a position, a function returning one, or
|
|
46
|
+
* undefined for the middle of the screen.
|
|
47
|
+
*/
|
|
48
|
+
get focus() {
|
|
49
|
+
return this.focus_;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
set focus(value) {
|
|
53
|
+
this.focus_ = value;
|
|
54
|
+
this.viewer.scene.requestRender();
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Strength of the blur and the streaks, 0 to 1.
|
|
59
|
+
*/
|
|
60
|
+
get strength() {
|
|
61
|
+
return this.strength_;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
set strength(value) {
|
|
65
|
+
this.strength_ = value;
|
|
66
|
+
if (this.stage_) {
|
|
67
|
+
this.stage_.enabled = value > 0;
|
|
68
|
+
}
|
|
69
|
+
this.viewer.scene.requestRender();
|
|
70
|
+
}
|
|
71
|
+
}
|
package/spotlight.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
import {Cartesian4, PixelDatatype} from '@cesium/core';
|
|
2
|
+
import {PostProcessStage, PostProcessStageComposite} from '@cesium/engine';
|
|
3
|
+
import {acquireTerrainDepth, releaseTerrainDepth} from './depth-test.js';
|
|
4
|
+
import Effect from './effect.js';
|
|
5
|
+
import {eyeFocus} from './focus.js';
|
|
6
|
+
import {heightUniforms} from './height.js';
|
|
7
|
+
import Beam from './shaders/Beam.js';
|
|
8
|
+
import EyeFromDepth from './shaders/EyeFromDepth.js';
|
|
9
|
+
import Filmic from './shaders/Filmic.js';
|
|
10
|
+
import Hash from './shaders/Hash.js';
|
|
11
|
+
import Noise from './shaders/Noise.js';
|
|
12
|
+
import Normal from './shaders/Normal.js';
|
|
13
|
+
import SpotlightShader from './shaders/Spotlight.js';
|
|
14
|
+
import SpotlightBeam from './shaders/SpotlightBeam.js';
|
|
15
|
+
import SpotlightBeamBlur from './shaders/SpotlightBeamBlur.js';
|
|
16
|
+
import SpotlightCone from './shaders/SpotlightCone.js';
|
|
17
|
+
|
|
18
|
+
const focusScratch = new Cartesian4();
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* A searchlight above the focus, pointing down: it throws a pool of warm
|
|
22
|
+
* light on the scene, shades the relief under it and lights up the haze in
|
|
23
|
+
* its beam, the rest darkens.
|
|
24
|
+
*/
|
|
25
|
+
export default class Spotlight extends Effect {
|
|
26
|
+
/**
|
|
27
|
+
* @param {import('@cesium/engine').CesiumWidget} viewer
|
|
28
|
+
* @param {{focus?: import('./focus.js').Focus, power?: number, radius?: number, softness?: number, darkness?: number, beam?: number, beamAnisotropy?: number}} [options]
|
|
29
|
+
*/
|
|
30
|
+
constructor(viewer, options = {}) {
|
|
31
|
+
super(viewer);
|
|
32
|
+
this.focus_ = options.focus;
|
|
33
|
+
this.power_ = options.power ?? 1;
|
|
34
|
+
this.radius_ = options.radius ?? 200;
|
|
35
|
+
this.softness_ = options.softness ?? 0.5;
|
|
36
|
+
this.darkness_ = options.darkness ?? 0.8;
|
|
37
|
+
this.beam_ = options.beam ?? 0.25;
|
|
38
|
+
this.beamAnisotropy_ = options.beamAnisotropy ?? 0.4;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @override
|
|
43
|
+
* @param {import('@cesium/engine').Scene} scene
|
|
44
|
+
*/
|
|
45
|
+
createStage_(scene) {
|
|
46
|
+
// SpotlightCone's uniforms, for all the passes
|
|
47
|
+
const cone = {
|
|
48
|
+
focus: () => eyeFocus(scene, this.focus_, focusScratch),
|
|
49
|
+
up: heightUniforms(scene).up,
|
|
50
|
+
radius: () => this.radius_,
|
|
51
|
+
softness: () => this.softness_,
|
|
52
|
+
};
|
|
53
|
+
// the beam is raymarched at half the resolution, then blurred at it
|
|
54
|
+
const beam = new PostProcessStage({
|
|
55
|
+
fragmentShader: EyeFromDepth + Hash + Noise + SpotlightCone + Beam + SpotlightBeam,
|
|
56
|
+
uniforms: {
|
|
57
|
+
...cone,
|
|
58
|
+
beam: () => this.beam_,
|
|
59
|
+
beamAnisotropy: () => this.beamAnisotropy_,
|
|
60
|
+
},
|
|
61
|
+
textureScale: 0.5,
|
|
62
|
+
pixelDatatype: PixelDatatype.HALF_FLOAT,
|
|
63
|
+
});
|
|
64
|
+
const blurredBeam = new PostProcessStage({
|
|
65
|
+
fragmentShader: SpotlightBeamBlur,
|
|
66
|
+
uniforms: {beamTexture: beam.name},
|
|
67
|
+
textureScale: 0.5,
|
|
68
|
+
pixelDatatype: PixelDatatype.HALF_FLOAT,
|
|
69
|
+
});
|
|
70
|
+
return new PostProcessStageComposite({
|
|
71
|
+
stages: [
|
|
72
|
+
beam,
|
|
73
|
+
blurredBeam,
|
|
74
|
+
new PostProcessStage({
|
|
75
|
+
fragmentShader: EyeFromDepth + Normal + Filmic + SpotlightCone + SpotlightShader,
|
|
76
|
+
uniforms: {
|
|
77
|
+
...cone,
|
|
78
|
+
beamTexture: blurredBeam.name,
|
|
79
|
+
darkness: () => this.darkness_,
|
|
80
|
+
beam: () => this.beam_,
|
|
81
|
+
power: () => this.power_,
|
|
82
|
+
},
|
|
83
|
+
}),
|
|
84
|
+
],
|
|
85
|
+
// the light is drawn over the scene, not over the beam
|
|
86
|
+
inputPreviousStageTexture: false,
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @override
|
|
92
|
+
* @param {import('@cesium/engine').Scene} scene
|
|
93
|
+
*/
|
|
94
|
+
activated_(scene) {
|
|
95
|
+
acquireTerrainDepth(scene);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @override
|
|
100
|
+
* @param {import('@cesium/engine').Scene} scene
|
|
101
|
+
*/
|
|
102
|
+
deactivating_(scene) {
|
|
103
|
+
releaseTerrainDepth(scene);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* What to light: a position, a function returning one, or undefined for
|
|
108
|
+
* what is in the middle of the screen.
|
|
109
|
+
*/
|
|
110
|
+
get focus() {
|
|
111
|
+
return this.focus_;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
set focus(value) {
|
|
115
|
+
this.focus_ = value;
|
|
116
|
+
this.viewer.scene.requestRender();
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Brightness of the light, 1 for the searchlight: the pool on the scene
|
|
121
|
+
* and the beam in the air scale with it.
|
|
122
|
+
*/
|
|
123
|
+
get power() {
|
|
124
|
+
return this.power_;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
set power(value) {
|
|
128
|
+
this.power_ = value;
|
|
129
|
+
this.viewer.scene.requestRender();
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Radius of the pool of light on flat ground, in meters. The light hangs
|
|
134
|
+
* twice as high above the focus.
|
|
135
|
+
*/
|
|
136
|
+
get radius() {
|
|
137
|
+
return this.radius_;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
set radius(value) {
|
|
141
|
+
this.radius_ = value;
|
|
142
|
+
this.viewer.scene.requestRender();
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Width of the penumbra, as a fraction of the radius.
|
|
147
|
+
*/
|
|
148
|
+
get softness() {
|
|
149
|
+
return this.softness_;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
set softness(value) {
|
|
153
|
+
this.softness_ = value;
|
|
154
|
+
this.viewer.scene.requestRender();
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Darkening outside the light, 0 to 1.
|
|
159
|
+
*/
|
|
160
|
+
get darkness() {
|
|
161
|
+
return this.darkness_;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
set darkness(value) {
|
|
165
|
+
this.darkness_ = value;
|
|
166
|
+
this.viewer.scene.requestRender();
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Brightness of the beam in the air, 0 to 1.
|
|
171
|
+
*/
|
|
172
|
+
get beam() {
|
|
173
|
+
return this.beam_;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
set beam(value) {
|
|
177
|
+
this.beam_ = value;
|
|
178
|
+
this.viewer.scene.requestRender();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Henyey-Greenstein asymmetry of the haze, 0 to 1: it scatters mostly
|
|
183
|
+
* forward, so the beam is brighter when looking toward the light.
|
|
184
|
+
*/
|
|
185
|
+
get beamAnisotropy() {
|
|
186
|
+
return this.beamAnisotropy_;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
set beamAnisotropy(value) {
|
|
190
|
+
this.beamAnisotropy_ = value;
|
|
191
|
+
this.viewer.scene.requestRender();
|
|
192
|
+
}
|
|
193
|
+
}
|
package/strikes.js
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// the strikes of a storm are few and short-lived: at most this many at once, each one over after this
|
|
2
|
+
// many seconds
|
|
3
|
+
export const MAX_STRIKES = 4;
|
|
4
|
+
export const STRIKE_LIFE = 1;
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Drops the strikes that are over and, at random, starts a new one: a Poisson process of the given
|
|
8
|
+
* rate, whatever the time between the frames.
|
|
9
|
+
* @template {{start: number}} T
|
|
10
|
+
* @param {T[]} strikes
|
|
11
|
+
* @param {number} now seconds
|
|
12
|
+
* @param {number} dt seconds since the last call
|
|
13
|
+
* @param {number} rate strikes per second
|
|
14
|
+
* @param {() => number} random in [0, 1)
|
|
15
|
+
* @param {(now: number) => T | undefined} create
|
|
16
|
+
*/
|
|
17
|
+
export function advanceStrikes(strikes, now, dt, rate, random, create) {
|
|
18
|
+
for (let i = strikes.length - 1; i >= 0; i--) {
|
|
19
|
+
if (now - strikes[i].start > STRIKE_LIFE) {
|
|
20
|
+
strikes.splice(i, 1);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (strikes.length < MAX_STRIKES && random() < 1 - Math.exp(-rate * dt)) {
|
|
24
|
+
// the create function declines a strike where it does not strike
|
|
25
|
+
const strike = create(now);
|
|
26
|
+
if (strike) {
|
|
27
|
+
strikes.push(strike);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
package/super8.js
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
import {PostProcessStage, PostProcessStageComposite} from '@cesium/engine';
|
|
2
|
+
import createBlur from './blur.js';
|
|
3
|
+
import Effect from './effect.js';
|
|
4
|
+
import {acquireFrames, releaseFrames} from './frame-clock.js';
|
|
5
|
+
import Frame from './shaders/Frame.js';
|
|
6
|
+
import Noise from './shaders/Noise.js';
|
|
7
|
+
import Super8Shader from './shaders/Super8.js';
|
|
8
|
+
|
|
9
|
+
// spread of the halation glow, the sigma and step of Cesium's blur stage, at half resolution:
|
|
10
|
+
// a glow this wide does not need more
|
|
11
|
+
const HALATION_SIGMA = 6;
|
|
12
|
+
const HALATION_STEP = 1;
|
|
13
|
+
const HALATION_SCALE = 0.5;
|
|
14
|
+
// Super 8 runs at 18 frames per second, as in Super8.glsl
|
|
15
|
+
const FRAME_RATE = 18;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* A Super 8 home movie: faded warm colors, halation, grain, gate weave,
|
|
19
|
+
* flicker, light leaks and the rounded corners of the camera gate. The film moves, so while
|
|
20
|
+
* active the scene renders at its 18 frames per second, also in requestRenderMode.
|
|
21
|
+
*/
|
|
22
|
+
export default class Super8 extends Effect {
|
|
23
|
+
/**
|
|
24
|
+
* @param {import('@cesium/engine').CesiumWidget} viewer
|
|
25
|
+
* @param {{fade?: number, halation?: number, grain?: number, weave?: number, flicker?: number, lightLeaks?: number, aspectRatio?: number}} [options]
|
|
26
|
+
*/
|
|
27
|
+
constructor(viewer, options = {}) {
|
|
28
|
+
super(viewer);
|
|
29
|
+
this.fade_ = options.fade ?? 0.5;
|
|
30
|
+
this.halation_ = options.halation ?? 0.5;
|
|
31
|
+
this.grain_ = options.grain ?? 0.15;
|
|
32
|
+
this.weave_ = options.weave ?? 1.5;
|
|
33
|
+
this.flicker_ = options.flicker ?? 0.08;
|
|
34
|
+
this.lightLeaks_ = options.lightLeaks ?? 0.5;
|
|
35
|
+
this.aspectRatio_ = options.aspectRatio ?? 4 / 3;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** @override */
|
|
39
|
+
createStage_() {
|
|
40
|
+
// a single level of composite: Cesium's texture cache hands the stage after a nested series
|
|
41
|
+
// of stages the output of that series instead of the scene
|
|
42
|
+
const blur = createBlur('czm_super8_halation', HALATION_SCALE);
|
|
43
|
+
const stage = new PostProcessStageComposite({
|
|
44
|
+
stages: [
|
|
45
|
+
blur,
|
|
46
|
+
new PostProcessStage({
|
|
47
|
+
fragmentShader: Frame + Noise + Super8Shader,
|
|
48
|
+
uniforms: {
|
|
49
|
+
blurTexture: blur.name,
|
|
50
|
+
time: () => performance.now() / 1000,
|
|
51
|
+
fade: () => this.fade_,
|
|
52
|
+
halation: () => this.halation_,
|
|
53
|
+
grain: () => this.grain_,
|
|
54
|
+
weave: () => this.weave_,
|
|
55
|
+
flicker: () => this.flicker_,
|
|
56
|
+
lightLeaks: () => this.lightLeaks_,
|
|
57
|
+
aspectRatio: () => this.aspectRatio_,
|
|
58
|
+
},
|
|
59
|
+
}),
|
|
60
|
+
],
|
|
61
|
+
// both read the scene
|
|
62
|
+
inputPreviousStageTexture: false,
|
|
63
|
+
uniforms: blur.uniforms,
|
|
64
|
+
});
|
|
65
|
+
stage.uniforms.sigma = HALATION_SIGMA;
|
|
66
|
+
stage.uniforms.stepSize = HALATION_STEP;
|
|
67
|
+
return stage;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* @override
|
|
72
|
+
* @param {import('@cesium/engine').Scene} scene
|
|
73
|
+
*/
|
|
74
|
+
activated_(scene) {
|
|
75
|
+
// a new picture only with each film frame, not with each frame of the display
|
|
76
|
+
acquireFrames(scene, FRAME_RATE);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @override
|
|
81
|
+
* @param {import('@cesium/engine').Scene} scene
|
|
82
|
+
*/
|
|
83
|
+
deactivating_(scene) {
|
|
84
|
+
releaseFrames(scene, FRAME_RATE);
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Faded colors: less saturation, lifted blacks, a warm cast; 0 to 1.
|
|
89
|
+
*/
|
|
90
|
+
get fade() {
|
|
91
|
+
return this.fade_;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
set fade(value) {
|
|
95
|
+
this.fade_ = value;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Warm glow bleeding around the highlights, 0 to 1.
|
|
100
|
+
*/
|
|
101
|
+
get halation() {
|
|
102
|
+
return this.halation_;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
set halation(value) {
|
|
106
|
+
this.halation_ = value;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Film grain, 0 to 1.
|
|
111
|
+
*/
|
|
112
|
+
get grain() {
|
|
113
|
+
return this.grain_;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
set grain(value) {
|
|
117
|
+
this.grain_ = value;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Drift of the picture in the gate, in CSS pixels.
|
|
122
|
+
*/
|
|
123
|
+
get weave() {
|
|
124
|
+
return this.weave_;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
set weave(value) {
|
|
128
|
+
this.weave_ = value;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* Change of brightness from frame to frame, 0 to 1.
|
|
133
|
+
*/
|
|
134
|
+
get flicker() {
|
|
135
|
+
return this.flicker_;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
set flicker(value) {
|
|
139
|
+
this.flicker_ = value;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* Warm light leaks along the edge, 0 to 1.
|
|
144
|
+
*/
|
|
145
|
+
get lightLeaks() {
|
|
146
|
+
return this.lightLeaks_;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
set lightLeaks(value) {
|
|
150
|
+
this.lightLeaks_ = value;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Width over height of the visible frame, with rounded corners; 0 for the
|
|
155
|
+
* whole canvas.
|
|
156
|
+
*/
|
|
157
|
+
get aspectRatio() {
|
|
158
|
+
return this.aspectRatio_;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
set aspectRatio(value) {
|
|
162
|
+
this.aspectRatio_ = value;
|
|
163
|
+
}
|
|
164
|
+
}
|
package/technicolor.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import {PostProcessStage} from '@cesium/engine';
|
|
2
|
+
import Effect from './effect.js';
|
|
3
|
+
import Frame from './shaders/Frame.js';
|
|
4
|
+
import TechnicolorShader from './shaders/Technicolor.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Three-strip Technicolor: dense, saturated primaries, as the films of the
|
|
8
|
+
* 1930s to 1950s.
|
|
9
|
+
*/
|
|
10
|
+
export default class Technicolor extends Effect {
|
|
11
|
+
/**
|
|
12
|
+
* @param {import('@cesium/engine').CesiumWidget} viewer
|
|
13
|
+
* @param {{strength?: number, aspectRatio?: number}} [options]
|
|
14
|
+
*/
|
|
15
|
+
constructor(viewer, options = {}) {
|
|
16
|
+
super(viewer);
|
|
17
|
+
this.strength_ = options.strength ?? 1;
|
|
18
|
+
this.aspectRatio_ = options.aspectRatio ?? 0;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
/** @override */
|
|
22
|
+
createStage_() {
|
|
23
|
+
return new PostProcessStage({
|
|
24
|
+
fragmentShader: Frame + TechnicolorShader,
|
|
25
|
+
uniforms: {
|
|
26
|
+
strength: () => this.strength_,
|
|
27
|
+
aspectRatio: () => this.aspectRatio_,
|
|
28
|
+
},
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* How far from the original colors, 0 to 1.
|
|
34
|
+
*/
|
|
35
|
+
get strength() {
|
|
36
|
+
return this.strength_;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
set strength(value) {
|
|
40
|
+
this.strength_ = value;
|
|
41
|
+
this.viewer.scene.requestRender();
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Width over height of the visible frame, black bars around it; 0 for the
|
|
46
|
+
* whole canvas. 1.37 is the Academy ratio of the era.
|
|
47
|
+
*/
|
|
48
|
+
get aspectRatio() {
|
|
49
|
+
return this.aspectRatio_;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
set aspectRatio(value) {
|
|
53
|
+
this.aspectRatio_ = value;
|
|
54
|
+
this.viewer.scene.requestRender();
|
|
55
|
+
}
|
|
56
|
+
}
|