@geoblocks/cesium-post-process 0.1.1 → 0.1.2
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/analog-video.js +2 -1
- package/cloud-map.js +2 -1
- package/cloud-noise.js +2 -1
- package/clouds.js +2 -2
- package/color-isolation.js +1 -2
- package/digital-video.js +2 -1
- package/drone-display.js +1 -1
- package/infrared.js +1 -2
- package/jello.js +2 -2
- package/lightning.js +5 -5
- package/motion-blur.js +2 -2
- package/package.json +2 -2
- package/precipitation.js +3 -3
- package/shaders/ColorIsolation.js +1 -1
- package/shaders/DigitalVideo.js +1 -1
- package/shaders/Infrared.js +1 -1
- package/shaders/SnowLine.js +1 -1
- package/shaders/Spotlight.js +1 -1
- package/shaders/Super8.js +1 -1
- package/shaders/TiltShift.js +1 -1
- package/shaders/Toy.js +1 -1
- package/shaders/WhiteModel.js +1 -1
- package/weather-map.js +6 -6
- package/shaders/Hsl.js +0 -2
package/analog-video.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {Math as CesiumMath} from '@cesium/core';
|
|
1
2
|
import {PostProcessStage} from '@cesium/engine';
|
|
2
3
|
import Effect from './effect.js';
|
|
3
4
|
import {acquireFrames, releaseFrames} from './frame-clock.js';
|
|
@@ -48,7 +49,7 @@ export function signalAt(seconds, interference) {
|
|
|
48
49
|
const weak = interference >= 1 ? 1 : interference * (0.75 + 0.25 * wander);
|
|
49
50
|
// a tear lasts two frames: decided once for each pair
|
|
50
51
|
const pair = Math.floor((seconds * FRAME_RATE) / 2) % 1000;
|
|
51
|
-
const chance = (2 * TEAR_RATE / FRAME_RATE) *
|
|
52
|
+
const chance = (2 * TEAR_RATE / FRAME_RATE) * CesiumMath.clamp((interference - 0.3) / 0.5, 0, 1);
|
|
52
53
|
const tear = interference < 1 && hash(pair, 11) < chance ? 0.2 + 0.6 * hash(pair, 13) : -1;
|
|
53
54
|
return {weak, tear};
|
|
54
55
|
}
|
package/cloud-map.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {Math as CesiumMath} from '@cesium/core';
|
|
1
2
|
import {imageData} from './weather-map.js';
|
|
2
3
|
|
|
3
4
|
// The clouds' map, from a map of the rain: a radar sees the rain, "not the small cloud droplets and
|
|
@@ -44,7 +45,7 @@ function boxBlur(values, width, height, radius, rows) {
|
|
|
44
45
|
}
|
|
45
46
|
let sum = 0;
|
|
46
47
|
for (let j = -radius; j <= radius; j++) {
|
|
47
|
-
sum += line[
|
|
48
|
+
sum += line[CesiumMath.clamp(j, 0, length - 1)];
|
|
48
49
|
}
|
|
49
50
|
for (let j = 0; j < length; j++) {
|
|
50
51
|
values[start + j * step] = sum / (2 * radius + 1);
|
package/cloud-noise.js
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
// edges. And a square of texels that tiles over the clouds' map, for CloudsDensity.glsl to read
|
|
7
7
|
// once rather than compute noise at each sample: red and green jitter the map's lookup, blue varies
|
|
8
8
|
// its coverage. Each channel is stretched over the bytes' range.
|
|
9
|
+
import {Math as CesiumMath} from '@cesium/core';
|
|
9
10
|
|
|
10
11
|
// cells of the base shape across the cube
|
|
11
12
|
const BASE_CELLS = 4;
|
|
@@ -49,7 +50,7 @@ function perlin(period, seed) {
|
|
|
49
50
|
const cx = c % period;
|
|
50
51
|
const cy = Math.floor(c / period) % period;
|
|
51
52
|
const cz = Math.floor(c / period ** 2);
|
|
52
|
-
const theta =
|
|
53
|
+
const theta = CesiumMath.TWO_PI * hash(cx, cy, cz, seed);
|
|
53
54
|
const cosPhi = 2 * hash(cx, cy, cz, seed + 1) - 1;
|
|
54
55
|
const sinPhi = Math.sqrt(1 - cosPhi * cosPhi);
|
|
55
56
|
gradients.set([sinPhi * Math.cos(theta), sinPhi * Math.sin(theta), cosPhi], 3 * c);
|
package/clouds.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Cartesian3, Ellipsoid, Matrix4, PixelDatatype, Rectangle} from '@cesium/core';
|
|
1
|
+
import {Cartesian3, Ellipsoid, Matrix4, PixelDatatype, Rectangle, Math as CesiumMath} from '@cesium/core';
|
|
2
2
|
import {PostProcessStage, PostProcessStageComposite, TextureMagnificationFilter, TextureMinificationFilter} from '@cesium/engine';
|
|
3
3
|
// @ts-expect-error the engine exports its 3D textures and samplers, but does not type them
|
|
4
4
|
import {Sampler, Texture3D, TextureWrap} from '@cesium/engine';
|
|
@@ -341,7 +341,7 @@ export default class Clouds extends Effect {
|
|
|
341
341
|
* @param {number} height meters
|
|
342
342
|
*/
|
|
343
343
|
shadowExtentFor_(height) {
|
|
344
|
-
return
|
|
344
|
+
return CesiumMath.clamp(SHADOW_SPREAD * height, SHADOW_EXTENTS[0], SHADOW_EXTENTS[1]);
|
|
345
345
|
}
|
|
346
346
|
|
|
347
347
|
/**
|
package/color-isolation.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import {PostProcessStage} from '@cesium/engine';
|
|
2
2
|
import Effect from './effect.js';
|
|
3
3
|
import ColorIsolationShader from './shaders/ColorIsolation.js';
|
|
4
|
-
import Hsl from './shaders/Hsl.js';
|
|
5
4
|
|
|
6
5
|
/**
|
|
7
6
|
* Color isolation: one hue keeps its color, the rest of the scene turns gray.
|
|
@@ -21,7 +20,7 @@ export default class ColorIsolation extends Effect {
|
|
|
21
20
|
/** @override */
|
|
22
21
|
createStage_() {
|
|
23
22
|
return new PostProcessStage({
|
|
24
|
-
fragmentShader:
|
|
23
|
+
fragmentShader: ColorIsolationShader,
|
|
25
24
|
uniforms: {
|
|
26
25
|
hue: () => this.hue_ / 360,
|
|
27
26
|
range: () => this.range_ / 360,
|
package/digital-video.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import {Math as CesiumMath} from '@cesium/core';
|
|
1
2
|
import {PostProcessStage} from '@cesium/engine';
|
|
2
3
|
import Effect from './effect.js';
|
|
3
4
|
import {acquireFrames, releaseFrames} from './frame-clock.js';
|
|
@@ -91,7 +92,7 @@ export default class DigitalVideo extends Effect {
|
|
|
91
92
|
return;
|
|
92
93
|
}
|
|
93
94
|
const t = (now - episode.start) / episode.duration;
|
|
94
|
-
this.severity_ = Math.max(0, Math.sin(
|
|
95
|
+
this.severity_ = Math.max(0, Math.sin(CesiumMath.PI * Math.min(t, 1))) ** 0.7 * (0.4 + 0.6 * this.breakup_);
|
|
95
96
|
this.blackout_ = episode.blackout && Math.abs(t - 0.5) * episode.duration < BLACKOUT / 2 ? 1 : 0;
|
|
96
97
|
}
|
|
97
98
|
|
package/drone-display.js
CHANGED
|
@@ -139,7 +139,7 @@ export default class DroneDisplay extends Effect {
|
|
|
139
139
|
throttle_() {
|
|
140
140
|
const seconds = performance.now() / 1000 - this.startTime_;
|
|
141
141
|
const wander = 2 * Math.sin(seconds * 0.3) * Math.sin(seconds * 0.13 + 1);
|
|
142
|
-
return Math.round(
|
|
142
|
+
return Math.round(CesiumMath.clamp(CRUISE_THROTTLE + CLIMB_THROTTLE * this.verticalSpeed_ + wander, 0, 100));
|
|
143
143
|
}
|
|
144
144
|
|
|
145
145
|
/**
|
package/infrared.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import {PostProcessStage} from '@cesium/engine';
|
|
2
2
|
import Effect from './effect.js';
|
|
3
|
-
import Hsl from './shaders/Hsl.js';
|
|
4
3
|
import InfraredShader from './shaders/Infrared.js';
|
|
5
4
|
|
|
6
5
|
/**
|
|
@@ -19,7 +18,7 @@ export default class Infrared extends Effect {
|
|
|
19
18
|
/** @override */
|
|
20
19
|
createStage_() {
|
|
21
20
|
return new PostProcessStage({
|
|
22
|
-
fragmentShader:
|
|
21
|
+
fragmentShader: InfraredShader,
|
|
23
22
|
uniforms: {
|
|
24
23
|
strength: () => this.strength_,
|
|
25
24
|
},
|
package/jello.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Cartesian4} from '@cesium/core';
|
|
1
|
+
import {Cartesian4, Math as CesiumMath} from '@cesium/core';
|
|
2
2
|
import {PostProcessStage} from '@cesium/engine';
|
|
3
3
|
import Effect from './effect.js';
|
|
4
4
|
import {acquireFrames, releaseFrames} from './frame-clock.js';
|
|
@@ -18,7 +18,7 @@ const MAX_ROTATION = 0.008;
|
|
|
18
18
|
// amplitude of the first sinusoid at full amount, per axis: x, y, rotation
|
|
19
19
|
const MAX_AMPLITUDES = [MAX_SHIFT, 0.5 * MAX_SHIFT, MAX_ROTATION];
|
|
20
20
|
|
|
21
|
-
const TAU =
|
|
21
|
+
const TAU = CesiumMath.TWO_PI;
|
|
22
22
|
/** @type {('x' | 'y' | 'z' | 'w')[]} one sinusoid per component */
|
|
23
23
|
const COMPONENTS = ['x', 'y', 'z', 'w'];
|
|
24
24
|
|
package/lightning.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Cartesian3, Cartesian4, Cartographic, Event, Matrix4} from '@cesium/core';
|
|
1
|
+
import {Cartesian3, Cartesian4, Cartographic, Event, Matrix4, Math as CesiumMath} from '@cesium/core';
|
|
2
2
|
import {PostProcessStage} from '@cesium/engine';
|
|
3
3
|
import {acquireTerrainDepth, releaseTerrainDepth} from './depth-test.js';
|
|
4
4
|
import Effect from './effect.js';
|
|
@@ -18,14 +18,14 @@ const MIN_DISTANCE = 300;
|
|
|
18
18
|
const MIN_CHANNEL = 500;
|
|
19
19
|
// longest time between two frames, in seconds, after a pause in requestRenderMode
|
|
20
20
|
const MAX_STEP = 0.1;
|
|
21
|
-
const TWO_PI =
|
|
21
|
+
const TWO_PI = CesiumMath.TWO_PI;
|
|
22
22
|
// the branches of a channel (Lightning.glsl's BRANCHES), the share of them that exist, and how far down
|
|
23
23
|
// the channel they leave it and at what angle from it, in radians, at most
|
|
24
24
|
const BRANCHES = 5;
|
|
25
25
|
const BRANCH_ODDS = 0.7;
|
|
26
26
|
const BRANCH_ANGLE = [0.25, 0.75];
|
|
27
27
|
// how far from the camera's heading a strike lands in front of it, in radians
|
|
28
|
-
const AHEAD =
|
|
28
|
+
const AHEAD = CesiumMath.PI / 6;
|
|
29
29
|
// the radar's intensity, 0 to 1, over which a point goes from never to always struck: from about
|
|
30
30
|
// 2.5 to 8 mm/h, the map being the square root of the rate over 10 mm/h
|
|
31
31
|
const STORM = [0.5, 0.9];
|
|
@@ -46,7 +46,7 @@ const ABOVE_FADE = 200;
|
|
|
46
46
|
* @param {number} x
|
|
47
47
|
*/
|
|
48
48
|
function smoothstep(edge0, edge1, x) {
|
|
49
|
-
const t =
|
|
49
|
+
const t = CesiumMath.clamp((x - edge0) / (edge1 - edge0), 0, 1);
|
|
50
50
|
return t * t * (3 - 2 * t);
|
|
51
51
|
}
|
|
52
52
|
|
|
@@ -114,7 +114,7 @@ export default class Lightning extends Effect {
|
|
|
114
114
|
}
|
|
115
115
|
return strike;
|
|
116
116
|
});
|
|
117
|
-
this.above_ =
|
|
117
|
+
this.above_ = CesiumMath.clamp((scene.camera.positionCartographic.height - this.cloudBase_ + ABOVE_FADE) / (2 * ABOVE_FADE), 0, 1);
|
|
118
118
|
const view = scene.camera.viewMatrix;
|
|
119
119
|
for (let i = 0; i < MAX_STRIKES; i++) {
|
|
120
120
|
const strike = this.strikes_[i];
|
package/motion-blur.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Matrix4, PixelDatatype} from '@cesium/core';
|
|
1
|
+
import {Matrix4, PixelDatatype, Math as CesiumMath} from '@cesium/core';
|
|
2
2
|
import {PostProcessStage, PostProcessStageComposite} from '@cesium/engine';
|
|
3
3
|
import {acquireTerrainDepth, releaseTerrainDepth} from './depth-test.js';
|
|
4
4
|
import Effect from './effect.js';
|
|
@@ -47,7 +47,7 @@ export default class MotionBlur extends Effect {
|
|
|
47
47
|
// in requestRenderMode, the time since the previous frame is not the time of the motion
|
|
48
48
|
exposureScale: () =>
|
|
49
49
|
(this.strength_ * this.exposure_) /
|
|
50
|
-
|
|
50
|
+
CesiumMath.clamp((performance.now() - this.previousTime_) / 1000, 1 / 240, 1 / 10),
|
|
51
51
|
},
|
|
52
52
|
textureScale: 0.5,
|
|
53
53
|
pixelDatatype: PixelDatatype.FLOAT,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@geoblocks/cesium-post-process",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"license": "BSD-3-Clause",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -53,5 +53,5 @@
|
|
|
53
53
|
"@cesium/core": ">=0.1.0",
|
|
54
54
|
"@cesium/engine": ">=10"
|
|
55
55
|
},
|
|
56
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "0abb7f3381fdf13b15d50047a46d3789f5f95a9e"
|
|
57
57
|
}
|
package/precipitation.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {Cartesian3, Cartesian4} from '@cesium/core';
|
|
1
|
+
import {Cartesian3, Cartesian4, Math as CesiumMath} from '@cesium/core';
|
|
2
2
|
import {PostProcessStage, PostProcessStageComposite} from '@cesium/engine';
|
|
3
3
|
// @ts-expect-error the engine exports its textures, framebuffers and render states, but does not type them
|
|
4
4
|
import {Framebuffer, RenderState, Texture} from '@cesium/engine';
|
|
@@ -45,7 +45,7 @@ const RAIN_EXPOSURE = 1 / 30;
|
|
|
45
45
|
const SNOW_EXPOSURE = 1 / 90;
|
|
46
46
|
// the longest trail, in cells: Precipitation.glsl looks one cell above each pixel's for it
|
|
47
47
|
const MAX_TRAIL = 1;
|
|
48
|
-
const TWO_PI =
|
|
48
|
+
const TWO_PI = CesiumMath.TWO_PI;
|
|
49
49
|
// the layers of drops, 2 to 16 m away, a drop every 0.05 rad around at the horizon in the nearest
|
|
50
50
|
// one, and the radius of its flakes in pixels, halved in each further layer (Precipitation.glsl's
|
|
51
51
|
// LAYERS, NEAREST, and the rest of its drops)
|
|
@@ -74,7 +74,7 @@ const CLOUD_BASE_FADE = 50;
|
|
|
74
74
|
* @param {number} x
|
|
75
75
|
*/
|
|
76
76
|
function smoothstep(edge0, edge1, x) {
|
|
77
|
-
const t =
|
|
77
|
+
const t = CesiumMath.clamp((x - edge0) / (edge1 - edge0), 0, 1);
|
|
78
78
|
return t * t * (3 - 2 * t);
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is automatically rebuilt from ColorIsolation.glsl.
|
|
2
|
-
export default "// Color isolation: one hue keeps its color, the rest of the scene turns gray. After prod80's\n// ReShade Color Isolation (MIT), https://github.com/prod80/prod80-ReShade-Repository\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// the hue kept and the half width of the selection, 0 to 1 for the whole circle\nuniform float hue;\nuniform float range;\n// 0 to 1\nuniform float strength;\nin vec2 v_textureCoordinates;\n\nvoid main() {\n vec4 sceneColor = texture(colorTexture, v_textureCoordinates);\n vec3 color = clamp(sceneColor.rgb, 0.0, 1.0);\n float gray =
|
|
2
|
+
export default "// Color isolation: one hue keeps its color, the rest of the scene turns gray. After prod80's\n// ReShade Color Isolation (MIT), https://github.com/prod80/prod80-ReShade-Repository\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// the hue kept and the half width of the selection, 0 to 1 for the whole circle\nuniform float hue;\nuniform float range;\n// 0 to 1\nuniform float strength;\nin vec2 v_textureCoordinates;\n\nvoid main() {\n vec4 sceneColor = texture(colorTexture, v_textureCoordinates);\n vec3 color = clamp(sceneColor.rgb, 0.0, 1.0);\n float gray = czm_luminance(color);\n float h = czm_RGBToHSL(color).x;\n // a triangle around the hue, on the circle\n float r = 1.0 / max(range, 1e-3);\n float weight = max(1.0 - abs((h - hue) * r), 0.0)\n + max(1.0 - abs((h + 1.0 - hue) * r), 0.0)\n + max(1.0 - abs((h - 1.0 - hue) * r), 0.0);\n float w = clamp(weight, 0.0, 1.0);\n float keep = w * w * w * (w * (w * 6.0 - 15.0) + 10.0);\n vec3 isolated = mix(vec3(gray), color, keep);\n out_FragColor = vec4(mix(color, isolated, strength), sceneColor.a);\n}\n";
|
package/shaders/DigitalVideo.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is automatically rebuilt from DigitalVideo.glsl.
|
|
2
|
-
export default "// A digital FPV video feed and its breakups: clean, slightly punchy colors, until a weak signal\n// breaks the picture into macroblocks, some displaced, strips shifted sideways and the color\n// channels split, and at worst a short black screen. A block keeps only its lowest frequencies,\n// as a codec that has thrown its detail away: a gradient between its corners, with fewer colors.\n// The displaced blocks and strips follow three.js's DigitalGlitch. Without the previous frames,\n// there are no freezes.\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// how broken the picture is, 0 to 1, and 1 during a black screen\nuniform float severity;\nuniform float blackout;\n// the video frame number, for the random patterns\nuniform float frame;\nin vec2 v_textureCoordinates;\n\n// a macroblock, in CSS pixels\nconst float BLOCK = 16.0;\n\nvoid main() {\n vec2 size = czm_viewport.zw;\n vec2 pixel = gl_FragCoord.xy / czm_pixelRatio;\n vec2 uv = v_textureCoordinates;\n vec4 sceneColor = texture(colorTexture, uv);\n // clean: slightly crushed blacks, a little more color\n vec3 rgb = sceneColor.rgb;\n rgb =
|
|
2
|
+
export default "// A digital FPV video feed and its breakups: clean, slightly punchy colors, until a weak signal\n// breaks the picture into macroblocks, some displaced, strips shifted sideways and the color\n// channels split, and at worst a short black screen. A block keeps only its lowest frequencies,\n// as a codec that has thrown its detail away: a gradient between its corners, with fewer colors.\n// The displaced blocks and strips follow three.js's DigitalGlitch. Without the previous frames,\n// there are no freezes.\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// how broken the picture is, 0 to 1, and 1 during a black screen\nuniform float severity;\nuniform float blackout;\n// the video frame number, for the random patterns\nuniform float frame;\nin vec2 v_textureCoordinates;\n\n// a macroblock, in CSS pixels\nconst float BLOCK = 16.0;\n\nvoid main() {\n vec2 size = czm_viewport.zw;\n vec2 pixel = gl_FragCoord.xy / czm_pixelRatio;\n vec2 uv = v_textureCoordinates;\n vec4 sceneColor = texture(colorTexture, uv);\n // clean: slightly crushed blacks, a little more color\n vec3 rgb = sceneColor.rgb;\n rgb = czm_saturation(rgb, 1.1);\n rgb = max(rgb - 0.02, 0.0) / 0.98;\n\n if (severity > 0.0) {\n // the pattern changes every few frames, as the decoder stutters\n float pattern = floor(frame / 3.0);\n // strips shifted sideways\n float strip = floor(pixel.y / (BLOCK * 2.0));\n if (hash(vec2(strip, pattern + 7.0)) < 0.25 * severity) {\n uv.x += (hash(vec2(strip, pattern + 11.0)) - 0.5) * 0.2 * severity;\n }\n // macroblocks: more of them as the signal gets worse; some show the picture displaced\n vec2 block = floor(uv * size / czm_pixelRatio / BLOCK);\n if (hash(block + pattern * 0.37) < 1.2 * severity) {\n vec2 displaced = hash(block + pattern + 3.0) < 0.3\n ? floor((vec2(hash(block + 5.0), hash(block + 9.0)) - 0.5) * 4.0)\n : vec2(0.0);\n vec2 cell = BLOCK * czm_pixelRatio / size;\n vec2 origin = (block + displaced) * cell;\n // the block's corners, and a gradient between them\n vec2 inset = 0.5 / size;\n vec3 c00 = texture(colorTexture, origin + inset).rgb;\n vec3 c10 = texture(colorTexture, origin + vec2(cell.x - inset.x, inset.y)).rgb;\n vec3 c01 = texture(colorTexture, origin + vec2(inset.x, cell.y - inset.y)).rgb;\n vec3 c11 = texture(colorTexture, origin + cell - inset).rgb;\n vec2 f = fract(uv * size / czm_pixelRatio / BLOCK);\n rgb = mix(mix(c00, c10, f.x), mix(c01, c11, f.x), f.y);\n // fewer colors\n float levels = mix(24.0, 6.0, severity);\n rgb = floor(rgb * levels + 0.5) / levels;\n } else if (uv != v_textureCoordinates) {\n rgb = texture(colorTexture, uv).rgb;\n }\n // the color channels split sideways\n vec2 split = vec2(3.0 * severity * czm_pixelRatio / size.x, 0.0);\n rgb.r = mix(rgb.r, texture(colorTexture, uv + split).r, severity);\n rgb.b = mix(rgb.b, texture(colorTexture, uv - split).b, severity);\n }\n out_FragColor = vec4(rgb * (1.0 - blackout), sceneColor.a);\n}\n";
|
package/shaders/Infrared.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is automatically rebuilt from Infrared.glsl.
|
|
2
|
-
export default "// Black and white infrared film: foliage, which reflects the near infrared, turns bright, the sky\n// and water dark. The gray is the lightness raised or lowered by a weight per hue. After prod80's\n// ReShade Black & White (MIT), its Infrared preset, https://github.com/prod80/prod80-ReShade-Repository\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// 0 to 1\nuniform float strength;\nin vec2 v_textureCoordinates;\n\n// weights of the red, yellow, green, cyan, blue and magenta hues\nconst float RED = -1.35;\nconst float YELLOW = 2.35;\nconst float GREEN = 1.35;\nconst float CYAN = -1.35;\nconst float BLUE = -1.6;\nconst float MAGENTA = -1.07;\n// shape of the hue selections\nconst float CURVE = 1.5;\n\nfloat curve(float x, float k) {\n float s = sign(x - 0.5);\n float o = 0.5 * (1.0 + s);\n return o - 0.5 * s * pow(max(2.0 * (o - s * x), 0.0), k);\n}\n\n// how much of the hue centered at center there is in hue\nfloat hueWeight(float hue, float center) {\n return curve(max(1.0 - abs((hue - center) * 6.0), 0.0), CURVE);\n}\n\nvoid main() {\n vec4 sceneColor = texture(colorTexture, v_textureCoordinates);\n vec3 hsl =
|
|
2
|
+
export default "// Black and white infrared film: foliage, which reflects the near infrared, turns bright, the sky\n// and water dark. The gray is the lightness raised or lowered by a weight per hue. After prod80's\n// ReShade Black & White (MIT), its Infrared preset, https://github.com/prod80/prod80-ReShade-Repository\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// 0 to 1\nuniform float strength;\nin vec2 v_textureCoordinates;\n\n// weights of the red, yellow, green, cyan, blue and magenta hues\nconst float RED = -1.35;\nconst float YELLOW = 2.35;\nconst float GREEN = 1.35;\nconst float CYAN = -1.35;\nconst float BLUE = -1.6;\nconst float MAGENTA = -1.07;\n// shape of the hue selections\nconst float CURVE = 1.5;\n\nfloat curve(float x, float k) {\n float s = sign(x - 0.5);\n float o = 0.5 * (1.0 + s);\n return o - 0.5 * s * pow(max(2.0 * (o - s * x), 0.0), k);\n}\n\n// how much of the hue centered at center there is in hue\nfloat hueWeight(float hue, float center) {\n return curve(max(1.0 - abs((hue - center) * 6.0), 0.0), CURVE);\n}\n\nvoid main() {\n vec4 sceneColor = texture(colorTexture, v_textureCoordinates);\n vec3 hsl = czm_RGBToHSL(clamp(sceneColor.rgb, 0.0, 1.0));\n float h = hsl.x;\n float weight = RED * (hueWeight(h, 0.0) + hueWeight(h, 1.0))\n + YELLOW * hueWeight(h, 1.0 / 6.0)\n + GREEN * hueWeight(h, 2.0 / 6.0)\n + CYAN * hueWeight(h, 3.0 / 6.0)\n + BLUE * hueWeight(h, 4.0 / 6.0)\n + MAGENTA * hueWeight(h, 5.0 / 6.0);\n float saturation = hsl.y * (1.0 - hsl.y) + hsl.y;\n float gray = clamp(hsl.z + hsl.z * weight * saturation * (1.0 - hsl.z), 0.0, 1.0);\n out_FragColor = vec4(mix(sceneColor.rgb, vec3(gray), strength), sceneColor.a);\n}\n";
|
package/shaders/SnowLine.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is automatically rebuilt from SnowLine.glsl.
|
|
2
|
-
export default "// Snow above an altitude, on slopes gentle enough to hold it, shaded by the sun and by the\n// brightness of the scene so that the relief stays readable. The slope comes from a normal\n// rebuilt from the neighboring pixels and smoothed over the facets of the terrain. Noise anchored\n// to the ground breaks up the edge of the snow, which lasts lower on the slopes away from the sun.\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\nuniform sampler2D depthTexture;\n// meters above the ellipsoid: half covered at the altitude, over a band transition meters high\nuniform float altitude;\nuniform float transition;\n// radians\nuniform float maxSlope;\n// 0 to 1\nuniform float coverage;\nin vec2 v_textureCoordinates;\n\nconst vec3 SNOW_SHADE = vec3(0.80, 0.87, 1.0);\nconst vec3 SNOW_SUN = vec3(1.0, 0.98, 0.94);\n// meters the snow line moves down on a slope facing away from the sun, and up on one facing it\nconst float ASPECT_SHIFT = 0.6;\n// meters the noise moves the snow line, as a fraction of the transition\nconst float NOISE_SHIFT = 0.8;\n// part of the snow that still covers the steep slopes at the limit, as a fraction of the coverage\nconst float STEEP_SNOW = 0.35;\n// half width of the slope limit, in radians (8 degrees), so that the snow thins out across the\n// facets of the terrain rather than stopping at their edges\nconst float SLOPE_EDGE = 0.14;\n\nfloat hash(vec3 p) {\n p = fract(p * 0.3183099 + 0.1);\n p *= 17.0;\n return fract(p.x * p.y * p.z * (p.x + p.y + p.z));\n}\n\nfloat valueNoise(vec3 p) {\n vec3 i = floor(p);\n vec3 f = fract(p);\n f = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(mix(hash(i), hash(i + vec3(1, 0, 0)), f.x), mix(hash(i + vec3(0, 1, 0)), hash(i + vec3(1, 1, 0)), f.x), f.y),\n mix(mix(hash(i + vec3(0, 0, 1)), hash(i + vec3(1, 0, 1)), f.x), mix(hash(i + vec3(0, 1, 1)), hash(i + vec3(1, 1, 1)), f.x), f.y),\n f.z);\n}\n\n// 0 to 1, from a few octaves anchored to the ground\nfloat groundNoise(vec3 world) {\n return 0.55 * valueNoise(world / 90.0) + 0.3 * valueNoise(world / 30.0) + 0.15 * valueNoise(world / 10.0);\n}\n\nvoid main() {\n vec4 sceneColor = texture(colorTexture, v_textureCoordinates);\n vec4 eye = eyeAt(depthTexture, v_textureCoordinates);\n vec3 normal = smoothNormalAt(depthTexture, v_textureCoordinates, eye.xyz);\n float slope = acos(clamp(dot(normal, up), -1.0, 1.0));\n\n float sun = max(dot(normal, czm_sunDirectionEC), 0.0);\n float noise = groundNoise((czm_inverseView * vec4(eye.xyz, 1.0)).xyz) - 0.5;\n // lower on the slopes away from the sun, irregular along the edge\n float shift = transition * (NOISE_SHIFT * noise + ASPECT_SHIFT * (0.5 - sun));\n float snowLine = altitude + shift;\n float snow = smoothstep(snowLine - 0.5 * transition, snowLine + 0.5 * transition, heightAt(eye.xyz));\n // opaque before the top of the band, so that the imagery does not show through the snow\n snow = smoothstep(0.0, 0.7, snow);\n // the steep slopes keep a thin, patchy cover, and the rock shows through\n float steep = smoothstep(maxSlope - SLOPE_EDGE, maxSlope + SLOPE_EDGE, slope);\n snow *= 1.0 - steep * (1.0 - STEEP_SNOW * smoothstep(0.35, 0.65, noise + 0.5));\n // eye.w is 0 for the sky\n snow *= coverage * eye.w;\n float brightness =
|
|
2
|
+
export default "// Snow above an altitude, on slopes gentle enough to hold it, shaded by the sun and by the\n// brightness of the scene so that the relief stays readable. The slope comes from a normal\n// rebuilt from the neighboring pixels and smoothed over the facets of the terrain. Noise anchored\n// to the ground breaks up the edge of the snow, which lasts lower on the slopes away from the sun.\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\nuniform sampler2D depthTexture;\n// meters above the ellipsoid: half covered at the altitude, over a band transition meters high\nuniform float altitude;\nuniform float transition;\n// radians\nuniform float maxSlope;\n// 0 to 1\nuniform float coverage;\nin vec2 v_textureCoordinates;\n\nconst vec3 SNOW_SHADE = vec3(0.80, 0.87, 1.0);\nconst vec3 SNOW_SUN = vec3(1.0, 0.98, 0.94);\n// meters the snow line moves down on a slope facing away from the sun, and up on one facing it\nconst float ASPECT_SHIFT = 0.6;\n// meters the noise moves the snow line, as a fraction of the transition\nconst float NOISE_SHIFT = 0.8;\n// part of the snow that still covers the steep slopes at the limit, as a fraction of the coverage\nconst float STEEP_SNOW = 0.35;\n// half width of the slope limit, in radians (8 degrees), so that the snow thins out across the\n// facets of the terrain rather than stopping at their edges\nconst float SLOPE_EDGE = 0.14;\n\nfloat hash(vec3 p) {\n p = fract(p * 0.3183099 + 0.1);\n p *= 17.0;\n return fract(p.x * p.y * p.z * (p.x + p.y + p.z));\n}\n\nfloat valueNoise(vec3 p) {\n vec3 i = floor(p);\n vec3 f = fract(p);\n f = f * f * (3.0 - 2.0 * f);\n return mix(\n mix(mix(hash(i), hash(i + vec3(1, 0, 0)), f.x), mix(hash(i + vec3(0, 1, 0)), hash(i + vec3(1, 1, 0)), f.x), f.y),\n mix(mix(hash(i + vec3(0, 0, 1)), hash(i + vec3(1, 0, 1)), f.x), mix(hash(i + vec3(0, 1, 1)), hash(i + vec3(1, 1, 1)), f.x), f.y),\n f.z);\n}\n\n// 0 to 1, from a few octaves anchored to the ground\nfloat groundNoise(vec3 world) {\n return 0.55 * valueNoise(world / 90.0) + 0.3 * valueNoise(world / 30.0) + 0.15 * valueNoise(world / 10.0);\n}\n\nvoid main() {\n vec4 sceneColor = texture(colorTexture, v_textureCoordinates);\n vec4 eye = eyeAt(depthTexture, v_textureCoordinates);\n vec3 normal = smoothNormalAt(depthTexture, v_textureCoordinates, eye.xyz);\n float slope = acos(clamp(dot(normal, up), -1.0, 1.0));\n\n float sun = max(dot(normal, czm_sunDirectionEC), 0.0);\n float noise = groundNoise((czm_inverseView * vec4(eye.xyz, 1.0)).xyz) - 0.5;\n // lower on the slopes away from the sun, irregular along the edge\n float shift = transition * (NOISE_SHIFT * noise + ASPECT_SHIFT * (0.5 - sun));\n float snowLine = altitude + shift;\n float snow = smoothstep(snowLine - 0.5 * transition, snowLine + 0.5 * transition, heightAt(eye.xyz));\n // opaque before the top of the band, so that the imagery does not show through the snow\n snow = smoothstep(0.0, 0.7, snow);\n // the steep slopes keep a thin, patchy cover, and the rock shows through\n float steep = smoothstep(maxSlope - SLOPE_EDGE, maxSlope + SLOPE_EDGE, slope);\n snow *= 1.0 - steep * (1.0 - STEEP_SNOW * smoothstep(0.35, 0.65, noise + 0.5));\n // eye.w is 0 for the sky\n snow *= coverage * eye.w;\n float brightness = czm_luminance(sceneColor.rgb);\n // blue in the shade, warm in the sun, with the relief of the scene kept in the brightness\n vec3 lit = mix(SNOW_SHADE, SNOW_SUN, sun) * clamp(0.68 + 0.25 * sun + 0.1 * brightness, 0.0, 1.0);\n out_FragColor = vec4(mix(sceneColor.rgb, lit, snow), sceneColor.a);\n}\n";
|
package/shaders/Spotlight.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is automatically rebuilt from Spotlight.glsl.
|
|
2
|
-
export default "// A searchlight above the focus, pointing down: it throws a pool of warm light radius meters\n// wide on flat ground, with a soft penumbra, shades the relief under it and lights up the haze\n// in its beam, from SpotlightBeam.glsl; the rest of the scene darkens and loses its color. The\n// cone and the falloff follow three.js's SpotLight. Needs EyeFromDepth, Normal, Filmic and\n// SpotlightCone.\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// the beam's haze and the log2 of the scene distance, at a fraction of the resolution\nuniform sampler2D beamTexture;\n// 0 to 1\nuniform float darkness;\n// brightness of the beam in the air, 0 to 1\nuniform float beam;\n// brightness of the light, 1 for the searchlight: the pool and the beam scale with it\nuniform float power;\nin vec2 v_textureCoordinates;\n\nconst vec3 LIGHT_COLOR = vec3(1.0, 0.93, 0.8);\nconst float INTENSITY = 1.4;\n// difference of the log2 of the distances, about 10 %, under which the beam's texels around a\n// pixel are interpolated\nconst float SOFT_DEPTH = 0.14;\n\n// light reaching a point fromLight away from the light: the cone around the axis with its\n// penumbra, and the inverse square, 1 at the focus, capped for what is close to the light\nfloat spotAt(vec3 fromLight, vec3 axis, float height, float coneCos, float penumbraCos) {\n float lightDistance = length(fromLight);\n float spot = smoothstep(coneCos, penumbraCos, dot(fromLight, -axis) / lightDistance);\n return spot * min(height * height / (lightDistance * lightDistance), 4.0);\n}\n\n// the beam's haze at the pixel, from the four texels of its lower resolution around it:\n// interpolated where they are all at the pixel's distance, else the one nearest to it, so that the\n// haze stops at the ridges in front of it rather than spilling onto them\nfloat beamAt(vec2 uv, float depth) {\n ivec2 size = textureSize(beamTexture, 0);\n vec2 position = uv * vec2(size) - 0.5;\n ivec2 base = ivec2(floor(position));\n vec2 f = fract(position);\n float interpolated = 0.0;\n float nearest = 0.0;\n float nearestGap = 1e38;\n float widestGap = 0.0;\n for (int i = 0; i < 4; i++) {\n ivec2 offset = ivec2(i & 1, i >> 1);\n vec2 texel = texelFetch(beamTexture, clamp(base + offset, ivec2(0), size - 1), 0).rg;\n float gap = abs(texel.g - depth);\n vec2 weights = mix(1.0 - f, f, vec2(offset));\n interpolated += weights.x * weights.y * texel.r;\n if (gap < nearestGap) {\n nearestGap = gap;\n nearest = texel.r;\n }\n widestGap = max(widestGap, gap);\n }\n return widestGap < SOFT_DEPTH ? interpolated : nearest;\n}\n\nvoid main() {\n vec4 sceneColor = texture(colorTexture, v_textureCoordinates);\n Cone spot;\n if (!spotlightCone(spot)) {\n out_FragColor = sceneColor;\n return;\n }\n vec3 color = sceneColor.rgb;\n vec3 ambient =
|
|
2
|
+
export default "// A searchlight above the focus, pointing down: it throws a pool of warm light radius meters\n// wide on flat ground, with a soft penumbra, shades the relief under it and lights up the haze\n// in its beam, from SpotlightBeam.glsl; the rest of the scene darkens and loses its color. The\n// cone and the falloff follow three.js's SpotLight. Needs EyeFromDepth, Normal, Filmic and\n// SpotlightCone.\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// the beam's haze and the log2 of the scene distance, at a fraction of the resolution\nuniform sampler2D beamTexture;\n// 0 to 1\nuniform float darkness;\n// brightness of the beam in the air, 0 to 1\nuniform float beam;\n// brightness of the light, 1 for the searchlight: the pool and the beam scale with it\nuniform float power;\nin vec2 v_textureCoordinates;\n\nconst vec3 LIGHT_COLOR = vec3(1.0, 0.93, 0.8);\nconst float INTENSITY = 1.4;\n// difference of the log2 of the distances, about 10 %, under which the beam's texels around a\n// pixel are interpolated\nconst float SOFT_DEPTH = 0.14;\n\n// light reaching a point fromLight away from the light: the cone around the axis with its\n// penumbra, and the inverse square, 1 at the focus, capped for what is close to the light\nfloat spotAt(vec3 fromLight, vec3 axis, float height, float coneCos, float penumbraCos) {\n float lightDistance = length(fromLight);\n float spot = smoothstep(coneCos, penumbraCos, dot(fromLight, -axis) / lightDistance);\n return spot * min(height * height / (lightDistance * lightDistance), 4.0);\n}\n\n// the beam's haze at the pixel, from the four texels of its lower resolution around it:\n// interpolated where they are all at the pixel's distance, else the one nearest to it, so that the\n// haze stops at the ridges in front of it rather than spilling onto them\nfloat beamAt(vec2 uv, float depth) {\n ivec2 size = textureSize(beamTexture, 0);\n vec2 position = uv * vec2(size) - 0.5;\n ivec2 base = ivec2(floor(position));\n vec2 f = fract(position);\n float interpolated = 0.0;\n float nearest = 0.0;\n float nearestGap = 1e38;\n float widestGap = 0.0;\n for (int i = 0; i < 4; i++) {\n ivec2 offset = ivec2(i & 1, i >> 1);\n vec2 texel = texelFetch(beamTexture, clamp(base + offset, ivec2(0), size - 1), 0).rg;\n float gap = abs(texel.g - depth);\n vec2 weights = mix(1.0 - f, f, vec2(offset));\n interpolated += weights.x * weights.y * texel.r;\n if (gap < nearestGap) {\n nearestGap = gap;\n nearest = texel.r;\n }\n widestGap = max(widestGap, gap);\n }\n return widestGap < SOFT_DEPTH ? interpolated : nearest;\n}\n\nvoid main() {\n vec4 sceneColor = texture(colorTexture, v_textureCoordinates);\n Cone spot;\n if (!spotlightCone(spot)) {\n out_FragColor = sceneColor;\n return;\n }\n vec3 color = sceneColor.rgb;\n vec3 ambient = czm_saturation(color, 1.0 - darkness) * (1.0 - darkness);\n vec4 eye = eyeAt(depthTexture, v_textureCoordinates);\n\n // eye.w is 0 for the sky, where the view ray goes on\n float sceneDistance = eye.w == 0.0 ? 1e30 : length(eye.xyz);\n float scattered = beam > 0.0 ? beamAt(v_textureCoordinates, log2(sceneDistance)) : 0.0;\n vec3 haze = LIGHT_COLOR * (power * beam * scattered);\n if (eye.w == 0.0) {\n out_FragColor = vec4(filmic(ambient + haze), sceneColor.a);\n return;\n }\n\n vec3 toLight = spot.light - eye.xyz;\n // the normal over wider steps where the surface is seen at a grazing angle, where the facets\n // of the terrain mesh would show as blotches; over fine ones elsewhere, for the relief\n vec3 coarse = normalize(normalAt(depthTexture, v_textureCoordinates, eye.xyz, 6.0 * czm_pixelRatio)\n + normalAt(depthTexture, v_textureCoordinates, eye.xyz, 18.0 * czm_pixelRatio));\n float grazing = smoothstep(0.7, 0.95, 1.0 - abs(dot(coarse, normalize(-eye.xyz))));\n vec3 normal = normalize(mix(smoothNormalAt(depthTexture, v_textureCoordinates, eye.xyz), coarse, grazing));\n float lambert = max(dot(normal, normalize(toLight)), 0.0);\n vec3 light = LIGHT_COLOR * (power * INTENSITY * spotAt(-toLight, up, spot.height, spot.coneCos, spot.penumbraCos) * lambert);\n out_FragColor = vec4(filmic(ambient + color * light + haze), sceneColor.a);\n}\n";
|
package/shaders/Super8.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is automatically rebuilt from Super8.glsl.
|
|
2
|
-
export default "// A Super 8 home movie: faded warm colors, halation around the highlights, heavy grain, the frame\n// drifting in the gate, flicker, light leaks, a strong vignette and the rounded corners of the\n// camera gate.\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// the scene blurred, for the halation\nuniform sampler2D blurTexture;\n// seconds\nuniform float time;\n// 0 to 1\nuniform float fade;\nuniform float grain;\n// in CSS pixels\nuniform float weave;\n// 0 to 1\nuniform float flicker;\nuniform float lightLeaks;\nuniform float halation;\n// width over height of the visible frame, 0 for the whole canvas\nuniform float aspectRatio;\nin vec2 v_textureCoordinates;\n\n// Super 8 runs at 18 frames per second\nconst float FRAME_RATE = 18.0;\n// radius of the rounded corners, as a fraction of the frame height\nconst float CORNER = 0.05;\nconst vec3 LEAK = vec3(1.0, 0.45, 0.15);\n// size of the grain clumps, in CSS pixels, and how much they differ between the dye layers\nconst float GRAIN_SIZE = 2.0;\nconst float GRAIN_COLOR = 0.3;\n// light scattered back through the film base is red-orange\nconst vec3 HALATION = vec3(1.0, 0.35, 0.15);\n\nfloat
|
|
2
|
+
export default "// A Super 8 home movie: faded warm colors, halation around the highlights, heavy grain, the frame\n// drifting in the gate, flicker, light leaks, a strong vignette and the rounded corners of the\n// camera gate.\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// the scene blurred, for the halation\nuniform sampler2D blurTexture;\n// seconds\nuniform float time;\n// 0 to 1\nuniform float fade;\nuniform float grain;\n// in CSS pixels\nuniform float weave;\n// 0 to 1\nuniform float flicker;\nuniform float lightLeaks;\nuniform float halation;\n// width over height of the visible frame, 0 for the whole canvas\nuniform float aspectRatio;\nin vec2 v_textureCoordinates;\n\n// Super 8 runs at 18 frames per second\nconst float FRAME_RATE = 18.0;\n// radius of the rounded corners, as a fraction of the frame height\nconst float CORNER = 0.05;\nconst vec3 LEAK = vec3(1.0, 0.45, 0.15);\n// size of the grain clumps, in CSS pixels, and how much they differ between the dye layers\nconst float GRAIN_SIZE = 2.0;\nconst float GRAIN_COLOR = 0.3;\n// light scattered back through the film base is red-orange\nconst vec3 HALATION = vec3(1.0, 0.35, 0.15);\n\nfloat hash(float n) {\n return fract(sin(n) * 43758.5453);\n}\n\n// smooth noise in [0, 1) over time\nfloat noise(float t) {\n float i = floor(t);\n float f = fract(t);\n return mix(hash(i), hash(i + 1.0), f * f * (3.0 - 2.0 * f));\n}\n\nvoid main() {\n vec2 size = czm_viewport.zw;\n // the time of the film frame, and its number for the noise\n float t = floor(time * FRAME_RATE) / FRAME_RATE;\n float frame = mod(floor(time * FRAME_RATE), 1000.0);\n\n // gate weave: the whole picture drifts by a pixel or two, from frame to frame\n vec2 drift = vec2(noise(t * 3.0), noise(t * 3.0 + 17.0)) * 2.0 - 1.0;\n vec2 uv = v_textureCoordinates + weave * czm_pixelRatio * drift / size;\n\n // the gate, with rounded corners, in pixels\n vec2 frameHalf = 0.5 * frameSize(aspectRatio) * size;\n float radius = CORNER * 2.0 * frameHalf.y;\n vec2 q = abs((v_textureCoordinates - 0.5) * size) - frameHalf + radius;\n float outside = length(max(q, 0.0)) + min(max(q.x, q.y), 0.0) - radius;\n float gate = 1.0 - smoothstep(-czm_pixelRatio, czm_pixelRatio, outside);\n // -0.5 to 0.5 inside the frame\n vec2 inFrame = (v_textureCoordinates - 0.5) * size / (2.0 * frameHalf);\n\n vec3 color = texture(colorTexture, uv).rgb;\n // faded film: less saturation, lifted blacks, a warm cast\n color = mix(color, vec3(czm_luminance(color)), 0.4 * fade);\n color = mix(color, color * vec3(1.05, 0.95, 0.78) * 0.88 + vec3(0.09, 0.07, 0.05), fade);\n // halation: a warm glow bleeding around the highlights\n float glow = smoothstep(0.45, 0.9, czm_luminance(texture(blurTexture, uv).rgb));\n color = 1.0 - (1.0 - color) * (1.0 - halation * glow * HALATION);\n // vignette\n color *= 1.0 - 0.6 * smoothstep(0.35, 0.85, length(inFrame));\n // a warm light leak, drifting along the right edge and coming and going\n vec2 leakAt = vec2(0.6, noise(time * 0.15) - 0.5);\n float leak = lightLeaks * smoothstep(0.3, 0.9, noise(time * 0.3 + 5.0)) * exp(-6.0 * dot(inFrame - leakAt, inFrame - leakAt));\n color = 1.0 - (1.0 - color) * (1.0 - leak * LEAK);\n // flicker: the brightness changes from frame to frame\n color *= 1.0 + flicker * (2.0 * hash(frame) - 1.0);\n // grain: clumps a few pixels wide, a new pattern with each film frame, a little different in\n // each dye layer, heaviest in the shadows and midtones and fading out in the highlights\n vec2 grainAt = gl_FragCoord.xy / (GRAIN_SIZE * czm_pixelRatio);\n float z = frame * 1.7 + 0.5;\n float mono = gradientNoise(grainAt, z);\n vec3 layers = vec3(gradientNoise(grainAt, z + 101.0), gradientNoise(grainAt, z + 211.0), gradientNoise(grainAt, z + 307.0));\n vec3 noise = mix(vec3(mono), layers, GRAIN_COLOR);\n float y = clamp(czm_luminance(color), 0.0, 1.0);\n color += grain * 1.4 * noise * 2.0 * (1.0 - y) * (0.5 + y);\n\n out_FragColor = vec4(clamp(color, 0.0, 1.0) * gate, 1.0);\n}\n";
|
package/shaders/TiltShift.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is automatically rebuilt from TiltShift.glsl.
|
|
2
|
-
export default "// Tilt-shift: a narrow band of sharpness around the focal distance and the blurred image further\n// off, with the punchy colors of miniature photographs. Distances compare as ratios, like a lens:\n// sharp within range factors of two of the focal distance, fully blurred at twice that. An\n// orthographic camera has no distance to compare: a band across the screen, as a miniature's fake,\n// sharp within range of the view's height above and below the focus, whatever stands there.\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\nuniform sampler2D blurTexture;\nuniform sampler2D depthTexture;\n// in eye coordinates; w is 0 for what is in the middle of the screen\nuniform vec4 focus;\n// in factors of two of the focal distance, or shares of the view's height (orthographic)\nuniform float range;\n// 0 to 1\nuniform float saturation;\nin vec2 v_textureCoordinates;\n\nvoid main() {\n vec4 target = focus.w > 0.0 ? focus : eyeAt(depthTexture, vec2(0.5));\n vec4 eye = eyeAt(depthTexture, v_textureCoordinates);\n float fromCamera = eye.w == 0.0 ? 1e30 : length(eye.xyz);\n // the orthographic view's height: its projection's y scale is 2 over it\n float off = czm_orthographicIn3D == 1.0\n ? abs(eye.y - target.y) * czm_projection[1][1] / 2.0\n : abs(log2(fromCamera / length(target.xyz)));\n // no blur without a focus in front of the camera (the sky in the middle, a focus behind)\n float blur = target.w > 0.0 && target.z < 0.0 ? smoothstep(range, 2.0 * range, off) : 0.0;\n vec4 sceneColor = mix(texture(colorTexture, v_textureCoordinates), texture(blurTexture, v_textureCoordinates), blur);\n\n vec3 color = sceneColor.rgb;\n color =
|
|
2
|
+
export default "// Tilt-shift: a narrow band of sharpness around the focal distance and the blurred image further\n// off, with the punchy colors of miniature photographs. Distances compare as ratios, like a lens:\n// sharp within range factors of two of the focal distance, fully blurred at twice that. An\n// orthographic camera has no distance to compare: a band across the screen, as a miniature's fake,\n// sharp within range of the view's height above and below the focus, whatever stands there.\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\nuniform sampler2D blurTexture;\nuniform sampler2D depthTexture;\n// in eye coordinates; w is 0 for what is in the middle of the screen\nuniform vec4 focus;\n// in factors of two of the focal distance, or shares of the view's height (orthographic)\nuniform float range;\n// 0 to 1\nuniform float saturation;\nin vec2 v_textureCoordinates;\n\nvoid main() {\n vec4 target = focus.w > 0.0 ? focus : eyeAt(depthTexture, vec2(0.5));\n vec4 eye = eyeAt(depthTexture, v_textureCoordinates);\n float fromCamera = eye.w == 0.0 ? 1e30 : length(eye.xyz);\n // the orthographic view's height: its projection's y scale is 2 over it\n float off = czm_orthographicIn3D == 1.0\n ? abs(eye.y - target.y) * czm_projection[1][1] / 2.0\n : abs(log2(fromCamera / length(target.xyz)));\n // no blur without a focus in front of the camera (the sky in the middle, a focus behind)\n float blur = target.w > 0.0 && target.z < 0.0 ? smoothstep(range, 2.0 * range, off) : 0.0;\n vec4 sceneColor = mix(texture(colorTexture, v_textureCoordinates), texture(blurTexture, v_textureCoordinates), blur);\n\n vec3 color = sceneColor.rgb;\n color = czm_saturation(color, 1.0 + saturation);\n color = mix(color, smoothstep(0.0, 1.0, color), saturation);\n out_FragColor = vec4(clamp(color, 0.0, 1.0), sceneColor.a);\n}\n";
|
package/shaders/Toy.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is automatically rebuilt from Toy.glsl.
|
|
2
|
-
export default "// A toy's look, as an isometric game's, after DepthEdges: the edges lit where the surface bends\n// outward and shaded where it bends inward, rounded as molded plastic close up; an outline along\n// the jumps, on their near side, a darker shade of the color; the colors a little richer and\n// warmer; the sky, if asked, a soft gradient.\n// its samplers read in high precision, whatever comes before (a phone's GPU's default is low)\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// how much brighter a convex edge gets, how much darker a concave one\nuniform float light;\nuniform float shade;\n// the edges' bevel, in meters, a pixel at the least; how much darker the outline, 0 for none\nuniform float bevel;\nuniform float outline;\n// the colors' saturation, and a factor each of red, green and blue\nuniform float saturation;\nuniform vec3 warm;\n// the sky's gradient, from the top of the screen to its bottom; w 0 to keep the sky\nuniform vec4 skyTop;\nuniform vec4 skyBottom;\nin vec2 v_textureCoordinates;\n\nvoid main() {\n vec2 uv = v_textureCoordinates;\n vec4 sceneColor = texture(colorTexture, uv);\n float c = depthAt(uv);\n if (c == SKY) {\n out_FragColor = skyTop.w > 0.0 ? vec4(skyAt(uv, skyTop, skyBottom), 1.0) : sceneColor;\n return;\n }\n float pixel = pixelAt(c);\n // the neighbors a bevel's width away: the bend measured over it, strongest on the edge and fading\n // to nothing a bevel off, a rounded edge's highlight\n float steps = clamp(bevel / pixel, 1.0, BEVEL);\n vec4 n = neighborsAt(uv, c, steps);\n float crease = creaseOf(n, steps * pixel, pixel);\n vec3 color = sceneColor.rgb * (n.x + n.y + n.z + n.w > 0.0 ? 1.0 + light * crease : 1.0 - shade * crease);\n if (outline > 0.0) {\n color *= 1.0 - outline * outlineAt(uv, c, n, steps, pixel);\n }\n color =
|
|
2
|
+
export default "// A toy's look, as an isometric game's, after DepthEdges: the edges lit where the surface bends\n// outward and shaded where it bends inward, rounded as molded plastic close up; an outline along\n// the jumps, on their near side, a darker shade of the color; the colors a little richer and\n// warmer; the sky, if asked, a soft gradient.\n// its samplers read in high precision, whatever comes before (a phone's GPU's default is low)\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// how much brighter a convex edge gets, how much darker a concave one\nuniform float light;\nuniform float shade;\n// the edges' bevel, in meters, a pixel at the least; how much darker the outline, 0 for none\nuniform float bevel;\nuniform float outline;\n// the colors' saturation, and a factor each of red, green and blue\nuniform float saturation;\nuniform vec3 warm;\n// the sky's gradient, from the top of the screen to its bottom; w 0 to keep the sky\nuniform vec4 skyTop;\nuniform vec4 skyBottom;\nin vec2 v_textureCoordinates;\n\nvoid main() {\n vec2 uv = v_textureCoordinates;\n vec4 sceneColor = texture(colorTexture, uv);\n float c = depthAt(uv);\n if (c == SKY) {\n out_FragColor = skyTop.w > 0.0 ? vec4(skyAt(uv, skyTop, skyBottom), 1.0) : sceneColor;\n return;\n }\n float pixel = pixelAt(c);\n // the neighbors a bevel's width away: the bend measured over it, strongest on the edge and fading\n // to nothing a bevel off, a rounded edge's highlight\n float steps = clamp(bevel / pixel, 1.0, BEVEL);\n vec4 n = neighborsAt(uv, c, steps);\n float crease = creaseOf(n, steps * pixel, pixel);\n vec3 color = sceneColor.rgb * (n.x + n.y + n.z + n.w > 0.0 ? 1.0 + light * crease : 1.0 - shade * crease);\n if (outline > 0.0) {\n color *= 1.0 - outline * outlineAt(uv, c, n, steps, pixel);\n }\n color = czm_saturation(color, saturation) * warm;\n out_FragColor = vec4(clamp(color, 0.0, 1.0), sceneColor.a);\n}\n";
|
package/shaders/WhiteModel.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
// This file is automatically rebuilt from WhiteModel.glsl.
|
|
2
|
-
export default "// A white model's look, as an architect's plaster model or clay render, after DepthEdges: every\n// color turned to its value and the values pressed into a narrow range of whites (an accent's hue\n// kept, if asked; the darkest left black, a section's poché), so the light and the shapes alone\n// tell the surfaces apart; darker where surfaces meet, an ambient obscurance from the depth; the\n// creases lit and shaded, a fine outline along the jumps; the sky, if asked, a pale gradient.\n// its samplers read in high precision, whatever comes before (a phone's GPU's default is low)\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// how much brighter a convex edge gets, how much darker a concave one\nuniform float light;\nuniform float shade;\n// the edges' bevel, in meters, a pixel at the least; how much darker the outline, 0 for none\nuniform float bevel;\nuniform float outline;\n// the colors' saturation, 0 for white, and a factor each of red, green and blue: the plaster's tint\nuniform float saturation;\nuniform vec3 warm;\n// the darkest and the lightest values, the scene's black and white; the value under which a color\n// keeps it, 0 for none\nuniform vec2 values;\nuniform float poche;\n// how much darker a corner gets, and how wide its shadow is, in meters\nuniform float occlusion;\nuniform float radius;\n// the sky's gradient, from the top of the screen to its bottom; w 0 to keep the sky\nuniform vec4 skyTop;\nuniform vec4 skyBottom;\nin vec2 v_textureCoordinates;\n\
|
|
2
|
+
export default "// A white model's look, as an architect's plaster model or clay render, after DepthEdges: every\n// color turned to its value and the values pressed into a narrow range of whites (an accent's hue\n// kept, if asked; the darkest left black, a section's poché), so the light and the shapes alone\n// tell the surfaces apart; darker where surfaces meet, an ambient obscurance from the depth; the\n// creases lit and shaded, a fine outline along the jumps; the sky, if asked, a pale gradient.\n// its samplers read in high precision, whatever comes before (a phone's GPU's default is low)\nprecision highp sampler2D;\nuniform sampler2D colorTexture;\n// how much brighter a convex edge gets, how much darker a concave one\nuniform float light;\nuniform float shade;\n// the edges' bevel, in meters, a pixel at the least; how much darker the outline, 0 for none\nuniform float bevel;\nuniform float outline;\n// the colors' saturation, 0 for white, and a factor each of red, green and blue: the plaster's tint\nuniform float saturation;\nuniform vec3 warm;\n// the darkest and the lightest values, the scene's black and white; the value under which a color\n// keeps it, 0 for none\nuniform vec2 values;\nuniform float poche;\n// how much darker a corner gets, and how wide its shadow is, in meters\nuniform float occlusion;\nuniform float radius;\n// the sky's gradient, from the top of the screen to its bottom; w 0 to keep the sky\nuniform vec4 skyTop;\nuniform vec4 skyBottom;\nin vec2 v_textureCoordinates;\n\n// the darkest colors' values, under the poché's, kept as they are rather than pressed into the\n// whites, fading into them over these shares of it: an architect's poché, solid black, or a text's\nconst vec2 POCHE = vec2(0.6, 1.4);\n// the occlusion: its widest, in pixels; its samples, on a spiral turned by the golden angle, the\n// spiral itself turned from pixel to pixel; how steeply above the surface a sample rises to count\n// (the normal from the depth is not exact), and how far from the pixel, in meters, a pixel and a\n// half at the least (the depth's own steps on a flat wall not counted); how many pixels wide the\n// disc is to show, fading in (zoomed out, its samples fall within the depth's noise)\nconst float RING = 48.0;\nconst int SAMPLES = 12;\nconst float GOLDEN = 2.39996;\nconst float BIAS = 0.15;\nconst float NEAREST = 0.05;\nconst vec2 SHOWN = vec2(3.0, 8.0);\n\n// how much the surfaces around uv close in over it, from 0 to 1, as the Alchemy ambient obscurance\n// (McGuire et al. 2011): the share of the samples around it, in a disc of the radius, that rise\n// above its surface (its normal from the depth's slopes), each the more as it rises steeper, none\n// farther than the radius; a corner's foot about a half, a flat floor none. p its eye coordinates, n\n// their slopes' normal\nfloat occludedAt(vec2 uv, vec3 p, vec3 n, float pixel) {\n float reach = min(radius, RING * pixel);\n float shown = smoothstep(SHOWN.x, SHOWN.y, reach / pixel);\n if (shown == 0.0) {\n return 0.0;\n }\n // turned toward the eye\n vec3 eye = czm_orthographicIn3D == 1.0 ? vec3(0.0, 0.0, 1.0) : normalize(-p);\n n = dot(n, eye) < 0.0 ? -n : n;\n float nearest = max(NEAREST, 1.5 * pixel);\n float spin = 6.2832 * fract(52.9829189 * fract(dot(gl_FragCoord.xy, vec2(0.06711056, 0.00583715))));\n float sum = 0.0;\n for (int i = 0; i < SAMPLES; i++) {\n float a = float(i) * GOLDEN + spin;\n vec2 o = vec2(cos(a), sin(a)) * (float(i) + 0.5) / float(SAMPLES) * reach / pixel / czm_viewport.zw;\n vec4 q = eyeAt(depthTexture, uv + o);\n vec3 v = q.xyz - p;\n float d = length(v);\n if (q.w > 0.0 && d > nearest) {\n sum += max(0.0, dot(v / d, n) - BIAS) * (1.0 - smoothstep(0.5 * reach, reach, d));\n }\n }\n return shown * sum / float(SAMPLES);\n}\n\nvoid main() {\n vec2 uv = v_textureCoordinates;\n // the surface's normal from the depth's slopes, read before any pixel returns, in step with its\n // neighbors\n vec3 p = eyeAt(depthTexture, uv).xyz;\n vec3 normal = normalize(cross(dFdx(p), dFdy(p)));\n vec4 sceneColor = texture(colorTexture, uv);\n float c = depthAt(uv);\n if (c == SKY) {\n out_FragColor = skyTop.w > 0.0 ? vec4(skyAt(uv, skyTop, skyBottom), 1.0) : sceneColor;\n return;\n }\n float pixel = pixelAt(c);\n // the color's value pressed between the darkest and the lightest, but the darkest's; its hue as\n // saturated as asked, scaled down rather than clipped where a channel would pass 1\n float value = czm_luminance(sceneColor.rgb);\n float kept = poche > 0.0 ? 1.0 - smoothstep(POCHE.x * poche, POCHE.y * poche, value) : 0.0;\n float pressed = mix(mix(values.x, values.y, value), value, kept);\n vec3 hue = sceneColor.rgb * pressed / max(value, 1e-4);\n vec3 color = mix(vec3(pressed), hue / max(1.0, max(hue.r, max(hue.g, hue.b))), saturation);\n float steps = clamp(bevel / pixel, 1.0, BEVEL);\n vec4 n = neighborsAt(uv, c, steps);\n float crease = creaseOf(n, steps * pixel, pixel);\n color *= n.x + n.y + n.z + n.w > 0.0 ? 1.0 + light * crease : 1.0 - shade * crease;\n if (occlusion > 0.0) {\n color *= 1.0 - occlusion * occludedAt(uv, p, normal, pixel);\n }\n if (outline > 0.0) {\n color *= 1.0 - outline * outlineAt(uv, c, n, steps, pixel);\n }\n out_FragColor = vec4(clamp(color * warm, 0.0, 1.0), sceneColor.a);\n}\n";
|
package/weather-map.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {Cartesian4} from '@cesium/core';
|
|
1
|
+
import {Cartesian4, Math as CesiumMath} from '@cesium/core';
|
|
2
2
|
// @ts-expect-error the engine exports its textures, but does not type them
|
|
3
3
|
import {Texture} from '@cesium/engine';
|
|
4
4
|
|
|
5
|
-
const TWO_PI =
|
|
5
|
+
const TWO_PI = CesiumMath.TWO_PI;
|
|
6
6
|
// the max map's texels are blocks of this many pixels of the map across
|
|
7
7
|
const POOL = 4;
|
|
8
8
|
|
|
@@ -154,9 +154,9 @@ export default class WeatherMap {
|
|
|
154
154
|
this.data_ = imageData(image);
|
|
155
155
|
Cartesian4.fromElements(
|
|
156
156
|
rectangle.west / TWO_PI + 0.5,
|
|
157
|
-
rectangle.south /
|
|
157
|
+
rectangle.south / CesiumMath.PI + 0.5,
|
|
158
158
|
TWO_PI / (rectangle.east - rectangle.west),
|
|
159
|
-
|
|
159
|
+
CesiumMath.PI / (rectangle.north - rectangle.south),
|
|
160
160
|
this.bounds,
|
|
161
161
|
);
|
|
162
162
|
}
|
|
@@ -233,8 +233,8 @@ export default class WeatherMap {
|
|
|
233
233
|
sample_(image, u, v) {
|
|
234
234
|
const {width, height, data} = image;
|
|
235
235
|
// the image's rows go down from the north
|
|
236
|
-
const x =
|
|
237
|
-
const y =
|
|
236
|
+
const x = CesiumMath.clamp(u * width - 0.5, 0, width - 1);
|
|
237
|
+
const y = CesiumMath.clamp((1 - v) * height - 0.5, 0, height - 1);
|
|
238
238
|
const x0 = Math.floor(x);
|
|
239
239
|
const y0 = Math.floor(y);
|
|
240
240
|
const x1 = Math.min(x0 + 1, width - 1);
|
package/shaders/Hsl.js
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
// This file is automatically rebuilt from Hsl.glsl.
|
|
2
|
-
export default "// Hue (0 to 1, red at 0), saturation and lightness of a color.\nvec3 rgbToHsl(vec3 color) {\n float maxc = max(color.r, max(color.g, color.b));\n float minc = min(color.r, min(color.g, color.b));\n float lightness = 0.5 * (maxc + minc);\n float delta = maxc - minc;\n if (delta < 1e-5) {\n return vec3(0.0, 0.0, lightness);\n }\n float saturation = lightness > 0.5 ? delta / (2.0 - maxc - minc) : delta / (maxc + minc);\n float hue = maxc == color.r ? (color.g - color.b) / delta + (color.g < color.b ? 6.0 : 0.0)\n : maxc == color.g ? (color.b - color.r) / delta + 2.0\n : (color.r - color.g) / delta + 4.0;\n return vec3(hue / 6.0, saturation, lightness);\n}\n";
|