@deck.gl/core
Version:
deck.gl core library
1,504 lines (1,418 loc) • 422 kB
JavaScript
"use strict";
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toCommonJS = (mod2) => __copyProps(__defProp({}, "__esModule", { value: true }), mod2);
// dist/index.js
var dist_exports = {};
__export(dist_exports, {
AmbientLight: () => AmbientLight,
Attribute: () => Attribute,
AttributeManager: () => AttributeManager,
COORDINATE_SYSTEM: () => COORDINATE_SYSTEM,
CompositeLayer: () => composite_layer_default,
Controller: () => Controller,
Deck: () => deck_default,
DeckRenderer: () => DeckRenderer,
DirectionalLight: () => DirectionalLight,
FirstPersonController: () => FirstPersonController,
FirstPersonView: () => first_person_view_default,
FirstPersonViewport: () => FirstPersonViewport,
FlyToInterpolator: () => FlyToInterpolator,
Layer: () => layer_default,
LayerExtension: () => layer_extension_default,
LayerManager: () => LayerManager,
LightingEffect: () => LightingEffect,
LinearInterpolator: () => LinearInterpolator,
MapController: () => MapController,
MapView: () => map_view_default,
OPERATION: () => OPERATION,
OrbitController: () => OrbitController,
OrbitView: () => orbit_view_default,
OrbitViewport: () => OrbitViewport,
OrthographicController: () => OrthographicController,
OrthographicView: () => orthographic_view_default,
OrthographicViewport: () => OrthographicViewport,
PointLight: () => PointLight,
PostProcessEffect: () => PostProcessEffect,
TRANSITION_EVENTS: () => TRANSITION_EVENTS,
Tesselator: () => Tesselator,
TransitionInterpolator: () => TransitionInterpolator,
UNIT: () => UNIT,
VERSION: () => VERSION,
View: () => View,
Viewport: () => viewport_default,
WebMercatorViewport: () => web_mercator_viewport_default,
Widget: () => Widget,
_CameraLight: () => CameraLight,
_Component: () => component_default,
_ComponentState: () => ComponentState,
_GlobeController: () => GlobeController,
_GlobeView: () => globe_view_default,
_GlobeViewport: () => GlobeViewport,
_LayersPass: () => LayersPass,
_PickLayersPass: () => PickLayersPass,
_SunLight: () => SunLight,
_applyStyles: () => applyStyles,
_compareProps: () => compareProps,
_count: () => count,
_deepEqual: () => deepEqual,
_fillArray: () => fillArray,
_flatten: () => flatten,
_memoize: () => memoize,
_mergeShaders: () => mergeShaders,
_removeStyles: () => removeStyles,
assert: () => assert,
color: () => color_default,
createIterable: () => createIterable,
fp64LowPart: () => fp64LowPart,
getShaderAssembler: () => getShaderAssembler,
gouraudMaterial: () => import_shadertools4.gouraudMaterial,
log: () => log_default,
phongMaterial: () => import_shadertools4.phongMaterial,
picking: () => picking_default,
project: () => project_default,
project32: () => project32_default,
shadow: () => shadow_default
});
module.exports = __toCommonJS(dist_exports);
// dist/lib/init.js
var import_core = require("@loaders.gl/core");
var import_images = require("@loaders.gl/images");
// dist/utils/log.js
var import_log = require("@probe.gl/log");
var defaultLogger = new import_log.Log({ id: "deck" });
var log_default = defaultLogger;
// dist/debug/loggers.js
var logState = {
attributeUpdateStart: -1,
attributeManagerUpdateStart: -1,
attributeUpdateMessages: []
};
var LOG_LEVEL_MAJOR_UPDATE = 1;
var LOG_LEVEL_MINOR_UPDATE = 2;
var LOG_LEVEL_UPDATE_DETAIL = 3;
var LOG_LEVEL_INFO = 4;
var LOG_LEVEL_DRAW = 2;
var getLoggers = (log) => ({
/* Layer events */
"layer.changeFlag": (layer, key, flags) => {
log.log(LOG_LEVEL_UPDATE_DETAIL, `${layer.id} ${key}: `, flags[key])();
},
"layer.initialize": (layer) => {
log.log(LOG_LEVEL_MAJOR_UPDATE, `Initializing ${layer}`)();
},
"layer.update": (layer, needsUpdate) => {
if (needsUpdate) {
const flags = layer.getChangeFlags();
log.log(LOG_LEVEL_MINOR_UPDATE, `Updating ${layer} because: ${Object.keys(flags).filter((key) => flags[key]).join(", ")}`)();
} else {
log.log(LOG_LEVEL_INFO, `${layer} does not need update`)();
}
},
"layer.matched": (layer, changed) => {
if (changed) {
log.log(LOG_LEVEL_INFO, `Matched ${layer}, state transfered`)();
}
},
"layer.finalize": (layer) => {
log.log(LOG_LEVEL_MAJOR_UPDATE, `Finalizing ${layer}`)();
},
/* CompositeLayer events */
"compositeLayer.renderLayers": (layer, updated, subLayers) => {
if (updated) {
log.log(LOG_LEVEL_MINOR_UPDATE, `Composite layer rendered new subLayers ${layer}`, subLayers)();
} else {
log.log(LOG_LEVEL_INFO, `Composite layer reused subLayers ${layer}`, subLayers)();
}
},
/* LayerManager events */
"layerManager.setLayers": (layerManager, updated, layers) => {
if (updated) {
log.log(LOG_LEVEL_MINOR_UPDATE, `Updating ${layers.length} deck layers`)();
}
},
"layerManager.activateViewport": (layerManager, viewport) => {
log.log(LOG_LEVEL_UPDATE_DETAIL, "Viewport changed", viewport)();
},
/* AttributeManager events */
"attributeManager.invalidate": (attributeManager, trigger, attributeNames) => {
log.log(LOG_LEVEL_MAJOR_UPDATE, attributeNames ? `invalidated attributes ${attributeNames} (${trigger}) for ${attributeManager.id}` : `invalidated all attributes for ${attributeManager.id}`)();
},
"attributeManager.updateStart": (attributeManager) => {
logState.attributeUpdateMessages.length = 0;
logState.attributeManagerUpdateStart = Date.now();
},
"attributeManager.updateEnd": (attributeManager, numInstances) => {
const timeMs = Math.round(Date.now() - logState.attributeManagerUpdateStart);
log.groupCollapsed(LOG_LEVEL_MINOR_UPDATE, `Updated attributes for ${numInstances} instances in ${attributeManager.id} in ${timeMs}ms`)();
for (const updateMessage of logState.attributeUpdateMessages) {
log.log(LOG_LEVEL_UPDATE_DETAIL, updateMessage)();
}
log.groupEnd(LOG_LEVEL_MINOR_UPDATE)();
},
/* Attribute events */
"attribute.updateStart": (attribute) => {
logState.attributeUpdateStart = Date.now();
},
"attribute.allocate": (attribute, numInstances) => {
const message = `${attribute.id} allocated ${numInstances}`;
logState.attributeUpdateMessages.push(message);
},
"attribute.updateEnd": (attribute, numInstances) => {
const timeMs = Math.round(Date.now() - logState.attributeUpdateStart);
const message = `${attribute.id} updated ${numInstances} in ${timeMs}ms`;
logState.attributeUpdateMessages.push(message);
},
/* Render events */
"deckRenderer.renderLayers": (deckRenderer, renderStats, opts) => {
const { pass, redrawReason, stats } = opts;
for (const status of renderStats) {
const { totalCount, visibleCount, compositeCount, pickableCount } = status;
const primitiveCount = totalCount - compositeCount;
const hiddenCount = primitiveCount - visibleCount;
log.log(LOG_LEVEL_DRAW, `RENDER #${deckRenderer.renderCount} ${visibleCount} (of ${totalCount} layers) to ${pass} because ${redrawReason} (${hiddenCount} hidden, ${compositeCount} composite ${pickableCount} pickable)`)();
if (stats) {
stats.get("Redraw Layers").add(visibleCount);
}
}
}
});
// dist/debug/index.js
var loggers = {};
if (true) {
loggers = getLoggers(log_default);
}
function register(handlers) {
loggers = handlers;
}
function debug(eventType, arg1, arg2, arg3) {
if (log_default.level > 0 && loggers[eventType]) {
loggers[eventType].call(null, arg1, arg2, arg3);
}
}
// dist/utils/json-loader.js
function isJSON(text) {
const firstChar = text[0];
const lastChar = text[text.length - 1];
return firstChar === "{" && lastChar === "}" || firstChar === "[" && lastChar === "]";
}
var json_loader_default = {
dataType: null,
batchType: null,
id: "JSON",
name: "JSON",
module: "",
version: "",
options: {},
extensions: ["json", "geojson"],
mimeTypes: ["application/json", "application/geo+json"],
testText: isJSON,
parseTextSync: JSON.parse
};
// dist/lib/init.js
function checkVersion() {
const version = true ? "9.2.2" : globalThis.DECK_VERSION || "untranspiled source";
const existingVersion = globalThis.deck && globalThis.deck.VERSION;
if (existingVersion && existingVersion !== version) {
throw new Error(`deck.gl - multiple versions detected: ${existingVersion} vs ${version}`);
}
if (!existingVersion) {
log_default.log(1, `deck.gl ${version}`)();
globalThis.deck = {
...globalThis.deck,
VERSION: version,
version,
log: log_default,
// experimental
_registerLoggers: register
};
(0, import_core.registerLoaders)([
json_loader_default,
// @ts-expect-error non-standard Loader format
[import_images.ImageLoader, { imagebitmap: { premultiplyAlpha: "none" } }]
]);
}
return version;
}
var VERSION = checkVersion();
// dist/shaderlib/index.js
var import_shadertools3 = require("@luma.gl/shadertools");
var import_shadertools4 = require("@luma.gl/shadertools");
// dist/shaderlib/misc/layer-uniforms.js
var uniformBlock = `uniform layerUniforms {
uniform float opacity;
} layer;
`;
var layerUniforms = {
name: "layer",
vs: uniformBlock,
fs: uniformBlock,
getUniforms: (props) => {
return {
// apply gamma to opacity to make it visually "linear"
// TODO - v10: use raw opacity?
opacity: Math.pow(props.opacity, 1 / 2.2)
};
},
uniformTypes: {
opacity: "f32"
}
};
// dist/shaderlib/color/color.js
var colorWGSL = (
/* WGSL */
`
struct ColorUniforms {
opacity: f32,
};
var<private> color: ColorUniforms = ColorUniforms(1.0);
// TODO (kaapp) avoiding binding index collisions to handle layer opacity
// requires some thought.
// @group(0) @binding(0) var<uniform> color: ColorUniforms;
@must_use
fn deckgl_premultiplied_alpha(fragColor: vec4<f32>) -> vec4<f32> {
return vec4(fragColor.rgb * fragColor.a, fragColor.a);
};
`
);
var color_default = {
name: "color",
dependencies: [],
source: colorWGSL,
getUniforms: (_props) => {
return {};
},
uniformTypes: {
opacity: "f32"
}
// @ts-ignore TODO v9.1
};
// dist/shaderlib/misc/geometry.js
var source = (
/* wgsl */
`const SMOOTH_EDGE_RADIUS: f32 = 0.5;
struct VertexGeometry {
position: vec4<f32>,
worldPosition: vec3<f32>,
worldPositionAlt: vec3<f32>,
normal: vec3<f32>,
uv: vec2<f32>,
pickingColor: vec3<f32>,
};
var<private> geometry_: VertexGeometry = VertexGeometry(
vec4<f32>(0.0, 0.0, 1.0, 0.0),
vec3<f32>(0.0, 0.0, 0.0),
vec3<f32>(0.0, 0.0, 0.0),
vec3<f32>(0.0, 0.0, 0.0),
vec2<f32>(0.0, 0.0),
vec3<f32>(0.0, 0.0, 0.0)
);
struct FragmentGeometry {
uv: vec2<f32>,
};
var<private> fragmentGeometry: FragmentGeometry;
fn smoothedge(edge: f32, x: f32) -> f32 {
return smoothstep(edge - SMOOTH_EDGE_RADIUS, edge + SMOOTH_EDGE_RADIUS, x);
}
`
);
var defines = "#define SMOOTH_EDGE_RADIUS 0.5";
var vs = (
/* glsl */
`${defines}
struct VertexGeometry {
vec4 position;
vec3 worldPosition;
vec3 worldPositionAlt;
vec3 normal;
vec2 uv;
vec3 pickingColor;
} geometry = VertexGeometry(
vec4(0.0, 0.0, 1.0, 0.0),
vec3(0.0),
vec3(0.0),
vec3(0.0),
vec2(0.0),
vec3(0.0)
);
`
);
var fs = (
/* glsl */
`${defines}
struct FragmentGeometry {
vec2 uv;
} geometry;
float smoothedge(float edge, float x) {
return smoothstep(edge - SMOOTH_EDGE_RADIUS, edge + SMOOTH_EDGE_RADIUS, x);
}
`
);
var geometry_default = {
name: "geometry",
source,
vs,
fs
};
// dist/shaderlib/project/project.js
var import_shadertools = require("@luma.gl/shadertools");
// dist/shaderlib/project/viewport-uniforms.js
var import_core2 = require("@math.gl/core");
// dist/lib/constants.js
var import_mjolnir = require("mjolnir.js");
var COORDINATE_SYSTEM = {
/**
* `LNGLAT` if rendering into a geospatial viewport, `CARTESIAN` otherwise
*/
DEFAULT: -1,
/**
* Positions are interpreted as [longitude, latitude, elevation]
* longitude/latitude are in degrees, elevation is in meters.
* Dimensions are in meters.
*/
LNGLAT: 1,
/**
* Positions are interpreted as [x, y, z] in meter offsets from the coordinate origin.
* Dimensions are in meters.
*/
METER_OFFSETS: 2,
/**
* Positions are interpreted as [deltaLng, deltaLat, elevation] from the coordinate origin.
* deltaLng/deltaLat are in degrees, elevation is in meters.
* Dimensions are in meters.
*/
LNGLAT_OFFSETS: 3,
/**
* Positions and dimensions are in the common units of the viewport.
*/
CARTESIAN: 0
};
Object.defineProperty(COORDINATE_SYSTEM, "IDENTITY", {
get: () => {
log_default.deprecated("COORDINATE_SYSTEM.IDENTITY", "COORDINATE_SYSTEM.CARTESIAN")();
return 0;
}
});
var PROJECTION_MODE = {
/**
* Render geospatial data in Web Mercator projection
*/
WEB_MERCATOR: 1,
/**
* Render geospatial data as a 3D globe
*/
GLOBE: 2,
/**
* (Internal use only) Web Mercator projection at high zoom
*/
WEB_MERCATOR_AUTO_OFFSET: 4,
/**
* No transformation
*/
IDENTITY: 0
};
var UNIT = {
common: 0,
meters: 1,
pixels: 2
};
var EVENT_HANDLERS = {
click: "onClick",
dblclick: "onClick",
panstart: "onDragStart",
panmove: "onDrag",
panend: "onDragEnd"
};
var RECOGNIZERS = {
multipan: [import_mjolnir.Pan, { threshold: 10, direction: import_mjolnir.InputDirection.Vertical, pointers: 2 }],
pinch: [import_mjolnir.Pinch, {}, null, ["multipan"]],
pan: [import_mjolnir.Pan, { threshold: 1 }, ["pinch"], ["multipan"]],
dblclick: [import_mjolnir.Tap, { event: "dblclick", taps: 2 }],
click: [import_mjolnir.Tap, { event: "click" }, null, ["dblclick"]]
};
var OPERATION = {
DRAW: "draw",
MASK: "mask",
TERRAIN: "terrain"
};
// dist/utils/memoize.js
function isEqual(a, b) {
if (a === b) {
return true;
}
if (Array.isArray(a)) {
const len = a.length;
if (!b || b.length !== len) {
return false;
}
for (let i = 0; i < len; i++) {
if (a[i] !== b[i]) {
return false;
}
}
return true;
}
return false;
}
function memoize(compute) {
let cachedArgs = {};
let cachedResult;
return (args) => {
for (const key in args) {
if (!isEqual(args[key], cachedArgs[key])) {
cachedResult = compute(args);
cachedArgs = args;
break;
}
}
return cachedResult;
};
}
// dist/shaderlib/project/viewport-uniforms.js
var ZERO_VECTOR = [0, 0, 0, 0];
var VECTOR_TO_POINT_MATRIX = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0];
var IDENTITY_MATRIX = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1];
var DEFAULT_PIXELS_PER_UNIT2 = [0, 0, 0];
var DEFAULT_COORDINATE_ORIGIN = [0, 0, 0];
var getMemoizedViewportUniforms = memoize(calculateViewportUniforms);
function getOffsetOrigin(viewport, coordinateSystem, coordinateOrigin = DEFAULT_COORDINATE_ORIGIN) {
if (coordinateOrigin.length < 3) {
coordinateOrigin = [coordinateOrigin[0], coordinateOrigin[1], 0];
}
let shaderCoordinateOrigin = coordinateOrigin;
let geospatialOrigin;
let offsetMode = true;
if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT_OFFSETS || coordinateSystem === COORDINATE_SYSTEM.METER_OFFSETS) {
geospatialOrigin = coordinateOrigin;
} else {
geospatialOrigin = viewport.isGeospatial ? (
// @ts-expect-error longitude and latitude are not defined on the base Viewport, but is expected on geospatial viewports
[Math.fround(viewport.longitude), Math.fround(viewport.latitude), 0]
) : null;
}
switch (viewport.projectionMode) {
case PROJECTION_MODE.WEB_MERCATOR:
if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT || coordinateSystem === COORDINATE_SYSTEM.CARTESIAN) {
geospatialOrigin = [0, 0, 0];
offsetMode = false;
}
break;
case PROJECTION_MODE.WEB_MERCATOR_AUTO_OFFSET:
if (coordinateSystem === COORDINATE_SYSTEM.LNGLAT) {
shaderCoordinateOrigin = geospatialOrigin;
} else if (coordinateSystem === COORDINATE_SYSTEM.CARTESIAN) {
shaderCoordinateOrigin = [
Math.fround(viewport.center[0]),
Math.fround(viewport.center[1]),
0
];
geospatialOrigin = viewport.unprojectPosition(shaderCoordinateOrigin);
shaderCoordinateOrigin[0] -= coordinateOrigin[0];
shaderCoordinateOrigin[1] -= coordinateOrigin[1];
shaderCoordinateOrigin[2] -= coordinateOrigin[2];
}
break;
case PROJECTION_MODE.IDENTITY:
shaderCoordinateOrigin = viewport.position.map(Math.fround);
shaderCoordinateOrigin[2] = shaderCoordinateOrigin[2] || 0;
break;
case PROJECTION_MODE.GLOBE:
offsetMode = false;
geospatialOrigin = null;
break;
default:
offsetMode = false;
}
return { geospatialOrigin, shaderCoordinateOrigin, offsetMode };
}
function calculateMatrixAndOffset(viewport, coordinateSystem, coordinateOrigin) {
const { viewMatrixUncentered, projectionMatrix } = viewport;
let { viewMatrix: viewMatrix2, viewProjectionMatrix } = viewport;
let projectionCenter = ZERO_VECTOR;
let originCommon = ZERO_VECTOR;
let cameraPosCommon = viewport.cameraPosition;
const { geospatialOrigin, shaderCoordinateOrigin, offsetMode } = getOffsetOrigin(viewport, coordinateSystem, coordinateOrigin);
if (offsetMode) {
originCommon = viewport.projectPosition(geospatialOrigin || shaderCoordinateOrigin);
cameraPosCommon = [
cameraPosCommon[0] - originCommon[0],
cameraPosCommon[1] - originCommon[1],
cameraPosCommon[2] - originCommon[2]
];
originCommon[3] = 1;
projectionCenter = import_core2.vec4.transformMat4([], originCommon, viewProjectionMatrix);
viewMatrix2 = viewMatrixUncentered || viewMatrix2;
viewProjectionMatrix = import_core2.mat4.multiply([], projectionMatrix, viewMatrix2);
viewProjectionMatrix = import_core2.mat4.multiply([], viewProjectionMatrix, VECTOR_TO_POINT_MATRIX);
}
return {
viewMatrix: viewMatrix2,
viewProjectionMatrix,
projectionCenter,
originCommon,
cameraPosCommon,
shaderCoordinateOrigin,
geospatialOrigin
};
}
function getUniformsFromViewport({
viewport,
devicePixelRatio = 1,
modelMatrix = null,
// Match Layer.defaultProps
coordinateSystem = COORDINATE_SYSTEM.DEFAULT,
coordinateOrigin = DEFAULT_COORDINATE_ORIGIN,
autoWrapLongitude = false
}) {
if (coordinateSystem === COORDINATE_SYSTEM.DEFAULT) {
coordinateSystem = viewport.isGeospatial ? COORDINATE_SYSTEM.LNGLAT : COORDINATE_SYSTEM.CARTESIAN;
}
const uniforms = getMemoizedViewportUniforms({
viewport,
devicePixelRatio,
coordinateSystem,
coordinateOrigin
});
uniforms.wrapLongitude = autoWrapLongitude;
uniforms.modelMatrix = modelMatrix || IDENTITY_MATRIX;
return uniforms;
}
function calculateViewportUniforms({ viewport, devicePixelRatio, coordinateSystem, coordinateOrigin }) {
const { projectionCenter, viewProjectionMatrix, originCommon, cameraPosCommon, shaderCoordinateOrigin, geospatialOrigin } = calculateMatrixAndOffset(viewport, coordinateSystem, coordinateOrigin);
const distanceScales = viewport.getDistanceScales();
const viewportSize = [
viewport.width * devicePixelRatio,
viewport.height * devicePixelRatio
];
const focalDistance = import_core2.vec4.transformMat4([], [0, 0, -viewport.focalDistance, 1], viewport.projectionMatrix)[3] || 1;
const uniforms = {
// Projection mode values
coordinateSystem,
projectionMode: viewport.projectionMode,
coordinateOrigin: shaderCoordinateOrigin,
commonOrigin: originCommon.slice(0, 3),
center: projectionCenter,
// Backward compatibility
// TODO: remove in v9
// @ts-expect-error _pseudoMeters is only defined on WebMercator viewport
pseudoMeters: Boolean(viewport._pseudoMeters),
// Screen size
viewportSize,
devicePixelRatio,
focalDistance,
commonUnitsPerMeter: distanceScales.unitsPerMeter,
commonUnitsPerWorldUnit: distanceScales.unitsPerMeter,
commonUnitsPerWorldUnit2: DEFAULT_PIXELS_PER_UNIT2,
scale: viewport.scale,
// This is the mercator scale (2 ** zoom)
wrapLongitude: false,
viewProjectionMatrix,
modelMatrix: IDENTITY_MATRIX,
// This is for lighting calculations
cameraPosition: cameraPosCommon
};
if (geospatialOrigin) {
const distanceScalesAtOrigin = viewport.getDistanceScales(geospatialOrigin);
switch (coordinateSystem) {
case COORDINATE_SYSTEM.METER_OFFSETS:
uniforms.commonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerMeter;
uniforms.commonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerMeter2;
break;
case COORDINATE_SYSTEM.LNGLAT:
case COORDINATE_SYSTEM.LNGLAT_OFFSETS:
if (!viewport._pseudoMeters) {
uniforms.commonUnitsPerMeter = distanceScalesAtOrigin.unitsPerMeter;
}
uniforms.commonUnitsPerWorldUnit = distanceScalesAtOrigin.unitsPerDegree;
uniforms.commonUnitsPerWorldUnit2 = distanceScalesAtOrigin.unitsPerDegree2;
break;
case COORDINATE_SYSTEM.CARTESIAN:
uniforms.commonUnitsPerWorldUnit = [1, 1, distanceScalesAtOrigin.unitsPerMeter[2]];
uniforms.commonUnitsPerWorldUnit2 = [0, 0, distanceScalesAtOrigin.unitsPerMeter2[2]];
break;
default:
break;
}
}
return uniforms;
}
// dist/shaderlib/project/project.wgsl.js
var COORDINATE_SYSTEM_WGSL_CONSTANTS = Object.keys(COORDINATE_SYSTEM).map((key) => `const COORDINATE_SYSTEM_${key}: i32 = ${COORDINATE_SYSTEM[key]};`).join("");
var PROJECTION_MODE_WGSL_CONSTANTS = Object.keys(PROJECTION_MODE).map((key) => `const PROJECTION_MODE_${key}: i32 = ${PROJECTION_MODE[key]};`).join("");
var UNIT_WGSL_CONSTANTS = Object.keys(UNIT).map((key) => `const UNIT_${key.toUpperCase()}: i32 = ${UNIT[key]};`).join("");
var projectWGSLHeader = (
/* wgsl */
`${COORDINATE_SYSTEM_WGSL_CONSTANTS}
${PROJECTION_MODE_WGSL_CONSTANTS}
${UNIT_WGSL_CONSTANTS}
const TILE_SIZE: f32 = 512.0;
const PI: f32 = 3.1415926536;
const WORLD_SCALE: f32 = TILE_SIZE / (PI * 2.0);
const ZERO_64_LOW: vec3<f32> = vec3<f32>(0.0, 0.0, 0.0);
const EARTH_RADIUS: f32 = 6370972.0; // meters
const GLOBE_RADIUS: f32 = 256.0;
// -----------------------------------------------------------------------------
// Uniform block (converted from GLSL uniform block)
// -----------------------------------------------------------------------------
struct ProjectUniforms {
wrapLongitude: i32,
coordinateSystem: i32,
commonUnitsPerMeter: vec3<f32>,
projectionMode: i32,
scale: f32,
commonUnitsPerWorldUnit: vec3<f32>,
commonUnitsPerWorldUnit2: vec3<f32>,
center: vec4<f32>,
modelMatrix: mat4x4<f32>,
viewProjectionMatrix: mat4x4<f32>,
viewportSize: vec2<f32>,
devicePixelRatio: f32,
focalDistance: f32,
cameraPosition: vec3<f32>,
coordinateOrigin: vec3<f32>,
commonOrigin: vec3<f32>,
pseudoMeters: i32,
};
@group(0) @binding(0)
var<uniform> project: ProjectUniforms;
// -----------------------------------------------------------------------------
// Geometry data
// (In your GLSL code, "geometry" was assumed to be available globally. In WGSL,
// you might supply this via vertex attributes or a uniform. Here we define a
// uniform struct for demonstration.)
// -----------------------------------------------------------------------------
// Structure to carry additional geometry data used by deck.gl filters.
struct Geometry {
worldPosition: vec3<f32>,
worldPositionAlt: vec3<f32>,
position: vec4<f32>,
normal: vec3<f32>,
uv: vec2<f32>,
pickingColor: vec3<f32>,
};
// @group(0) @binding(1)
var<private> geometry: Geometry;
`
);
var projectWGSL = (
/* wgsl */
`${projectWGSLHeader}
// -----------------------------------------------------------------------------
// Functions
// -----------------------------------------------------------------------------
// Returns an adjustment factor for commonUnitsPerMeter
fn _project_size_at_latitude(lat: f32) -> f32 {
let y = clamp(lat, -89.9, 89.9);
return 1.0 / cos(radians(y));
}
// Overloaded version: scales a value in meters at a given latitude.
fn _project_size_at_latitude_m(meters: f32, lat: f32) -> f32 {
return meters * project.commonUnitsPerMeter.z * _project_size_at_latitude(lat);
}
// Computes a non-linear scale factor based on geometry.
// (Note: This function relies on "geometry" being provided.)
fn project_size() -> f32 {
if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR &&
project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT &&
project.pseudoMeters == 0) {
if (geometry.position.w == 0.0) {
return _project_size_at_latitude(geometry.worldPosition.y);
}
let y: f32 = geometry.position.y / TILE_SIZE * 2.0 - 1.0;
let y2 = y * y;
let y4 = y2 * y2;
let y6 = y4 * y2;
return 1.0 + 4.9348 * y2 + 4.0587 * y4 + 1.5642 * y6;
}
return 1.0;
}
// Overloads to scale offsets (meters to world units)
fn project_size_float(meters: f32) -> f32 {
return meters * project.commonUnitsPerMeter.z * project_size();
}
fn project_size_vec2(meters: vec2<f32>) -> vec2<f32> {
return meters * project.commonUnitsPerMeter.xy * project_size();
}
fn project_size_vec3(meters: vec3<f32>) -> vec3<f32> {
return meters * project.commonUnitsPerMeter * project_size();
}
fn project_size_vec4(meters: vec4<f32>) -> vec4<f32> {
return vec4<f32>(meters.xyz * project.commonUnitsPerMeter, meters.w);
}
// Returns a rotation matrix aligning the z\u2011axis with the given up vector.
fn project_get_orientation_matrix(up: vec3<f32>) -> mat3x3<f32> {
let uz = normalize(up);
let ux = select(
vec3<f32>(1.0, 0.0, 0.0),
normalize(vec3<f32>(uz.y, -uz.x, 0.0)),
abs(uz.z) == 1.0
);
let uy = cross(uz, ux);
return mat3x3<f32>(ux, uy, uz);
}
// Since WGSL does not support "out" parameters, we return a struct.
struct RotationResult {
needsRotation: bool,
transform: mat3x3<f32>,
};
fn project_needs_rotation(commonPosition: vec3<f32>) -> RotationResult {
if (project.projectionMode == PROJECTION_MODE_GLOBE) {
return RotationResult(true, project_get_orientation_matrix(commonPosition));
} else {
return RotationResult(false, mat3x3<f32>()); // identity alternative if needed
};
}
// Projects a normal vector from the current coordinate system to world space.
fn project_normal(vector: vec3<f32>) -> vec3<f32> {
let normal_modelspace = project.modelMatrix * vec4<f32>(vector, 0.0);
var n = normalize(normal_modelspace.xyz * project.commonUnitsPerMeter);
let rotResult = project_needs_rotation(geometry.position.xyz);
if (rotResult.needsRotation) {
n = rotResult.transform * n;
}
return n;
}
// Applies a scale offset based on y-offset (dy)
fn project_offset_(offset: vec4<f32>) -> vec4<f32> {
let dy: f32 = offset.y;
let commonUnitsPerWorldUnit = project.commonUnitsPerWorldUnit + project.commonUnitsPerWorldUnit2 * dy;
return vec4<f32>(offset.xyz * commonUnitsPerWorldUnit, offset.w);
}
// Projects lng/lat coordinates to a unit tile [0,1]
fn project_mercator_(lnglat: vec2<f32>) -> vec2<f32> {
var x = lnglat.x;
if (project.wrapLongitude != 0) {
x = ((x + 180.0) % 360.0) - 180.0;
}
let y = clamp(lnglat.y, -89.9, 89.9);
return vec2<f32>(
radians(x) + PI,
PI + log(tan(PI * 0.25 + radians(y) * 0.5))
) * WORLD_SCALE;
}
// Projects lng/lat/z coordinates for a globe projection.
fn project_globe_(lnglatz: vec3<f32>) -> vec3<f32> {
let lambda = radians(lnglatz.x);
let phi = radians(lnglatz.y);
let cosPhi = cos(phi);
let D = (lnglatz.z / EARTH_RADIUS + 1.0) * GLOBE_RADIUS;
return vec3<f32>(
sin(lambda) * cosPhi,
-cos(lambda) * cosPhi,
sin(phi)
) * D;
}
// Projects positions (with an optional 64-bit low part) from the input
// coordinate system to the common space.
fn project_position_vec4_f64(position: vec4<f32>, position64Low: vec3<f32>) -> vec4<f32> {
var position_world = project.modelMatrix * position;
// Work around for a Mac+NVIDIA bug:
if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR) {
if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
return vec4<f32>(
project_mercator_(position_world.xy),
_project_size_at_latitude_m(position_world.z, position_world.y),
position_world.w
);
}
if (project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN) {
position_world = vec4f(position_world.xyz + project.coordinateOrigin, position_world.w);
}
}
if (project.projectionMode == PROJECTION_MODE_GLOBE) {
if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
return vec4<f32>(
project_globe_(position_world.xyz),
position_world.w
);
}
}
if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET) {
if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
if (abs(position_world.y - project.coordinateOrigin.y) > 0.25) {
return vec4<f32>(
project_mercator_(position_world.xy) - project.commonOrigin.xy,
project_size_float(position_world.z),
position_world.w
);
}
}
}
if (project.projectionMode == PROJECTION_MODE_IDENTITY ||
(project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET &&
(project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT ||
project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN))) {
position_world = vec4f(position_world.xyz - project.coordinateOrigin, position_world.w);
}
return project_offset_(position_world) +
project_offset_(project.modelMatrix * vec4<f32>(position64Low, 0.0));
}
// Overloaded versions for different input types.
fn project_position_vec4_f32(position: vec4<f32>) -> vec4<f32> {
return project_position_vec4_f64(position, ZERO_64_LOW);
}
fn project_position_vec3_f64(position: vec3<f32>, position64Low: vec3<f32>) -> vec3<f32> {
let projected_position = project_position_vec4_f64(vec4<f32>(position, 1.0), position64Low);
return projected_position.xyz;
}
fn project_position_vec3_f32(position: vec3<f32>) -> vec3<f32> {
let projected_position = project_position_vec4_f64(vec4<f32>(position, 1.0), ZERO_64_LOW);
return projected_position.xyz;
}
fn project_position_vec2_f32(position: vec2<f32>) -> vec2<f32> {
let projected_position = project_position_vec4_f64(vec4<f32>(position, 0.0, 1.0), ZERO_64_LOW);
return projected_position.xy;
}
// Transforms a common space position to clip space.
fn project_common_position_to_clipspace_with_projection(position: vec4<f32>, viewProjectionMatrix: mat4x4<f32>, center: vec4<f32>) -> vec4<f32> {
return viewProjectionMatrix * position + center;
}
// Uses the project viewProjectionMatrix and center.
fn project_common_position_to_clipspace(position: vec4<f32>) -> vec4<f32> {
return project_common_position_to_clipspace_with_projection(position, project.viewProjectionMatrix, project.center);
}
// Returns a clip space offset corresponding to a given number of screen pixels.
fn project_pixel_size_to_clipspace(pixels: vec2<f32>) -> vec2<f32> {
let offset = pixels / project.viewportSize * project.devicePixelRatio * 2.0;
return offset * project.focalDistance;
}
fn project_meter_size_to_pixel(meters: f32) -> f32 {
return project_size_float(meters) * project.scale;
}
fn project_unit_size_to_pixel(size: f32, unit: i32) -> f32 {
if (unit == UNIT_METERS) {
return project_meter_size_to_pixel(size);
} else if (unit == UNIT_COMMON) {
return size * project.scale;
}
// UNIT_PIXELS: no scaling applied.
return size;
}
fn project_pixel_size_float(pixels: f32) -> f32 {
return pixels / project.scale;
}
fn project_pixel_size_vec2(pixels: vec2<f32>) -> vec2<f32> {
return pixels / project.scale;
}
`
);
// dist/shaderlib/project/project.glsl.js
var COORDINATE_SYSTEM_GLSL_CONSTANTS = Object.keys(COORDINATE_SYSTEM).map((key) => `const int COORDINATE_SYSTEM_${key} = ${COORDINATE_SYSTEM[key]};`).join("");
var PROJECTION_MODE_GLSL_CONSTANTS = Object.keys(PROJECTION_MODE).map((key) => `const int PROJECTION_MODE_${key} = ${PROJECTION_MODE[key]};`).join("");
var UNIT_GLSL_CONSTANTS = Object.keys(UNIT).map((key) => `const int UNIT_${key.toUpperCase()} = ${UNIT[key]};`).join("");
var projectGLSL = (
/* glsl */
`${COORDINATE_SYSTEM_GLSL_CONSTANTS}
${PROJECTION_MODE_GLSL_CONSTANTS}
${UNIT_GLSL_CONSTANTS}
uniform projectUniforms {
bool wrapLongitude;
int coordinateSystem;
vec3 commonUnitsPerMeter;
int projectionMode;
float scale;
vec3 commonUnitsPerWorldUnit;
vec3 commonUnitsPerWorldUnit2;
vec4 center;
mat4 modelMatrix;
mat4 viewProjectionMatrix;
vec2 viewportSize;
float devicePixelRatio;
float focalDistance;
vec3 cameraPosition;
vec3 coordinateOrigin;
vec3 commonOrigin;
bool pseudoMeters;
} project;
const float TILE_SIZE = 512.0;
const float PI = 3.1415926536;
const float WORLD_SCALE = TILE_SIZE / (PI * 2.0);
const vec3 ZERO_64_LOW = vec3(0.0);
const float EARTH_RADIUS = 6370972.0;
const float GLOBE_RADIUS = 256.0;
float project_size_at_latitude(float lat) {
float y = clamp(lat, -89.9, 89.9);
return 1.0 / cos(radians(y));
}
float project_size() {
if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR &&
project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT &&
project.pseudoMeters == false) {
if (geometry.position.w == 0.0) {
return project_size_at_latitude(geometry.worldPosition.y);
}
float y = geometry.position.y / TILE_SIZE * 2.0 - 1.0;
float y2 = y * y;
float y4 = y2 * y2;
float y6 = y4 * y2;
return 1.0 + 4.9348 * y2 + 4.0587 * y4 + 1.5642 * y6;
}
return 1.0;
}
float project_size_at_latitude(float meters, float lat) {
return meters * project.commonUnitsPerMeter.z * project_size_at_latitude(lat);
}
float project_size(float meters) {
return meters * project.commonUnitsPerMeter.z * project_size();
}
vec2 project_size(vec2 meters) {
return meters * project.commonUnitsPerMeter.xy * project_size();
}
vec3 project_size(vec3 meters) {
return meters * project.commonUnitsPerMeter * project_size();
}
vec4 project_size(vec4 meters) {
return vec4(meters.xyz * project.commonUnitsPerMeter, meters.w);
}
mat3 project_get_orientation_matrix(vec3 up) {
vec3 uz = normalize(up);
vec3 ux = abs(uz.z) == 1.0 ? vec3(1.0, 0.0, 0.0) : normalize(vec3(uz.y, -uz.x, 0));
vec3 uy = cross(uz, ux);
return mat3(ux, uy, uz);
}
bool project_needs_rotation(vec3 commonPosition, out mat3 transform) {
if (project.projectionMode == PROJECTION_MODE_GLOBE) {
transform = project_get_orientation_matrix(commonPosition);
return true;
}
return false;
}
vec3 project_normal(vec3 vector) {
vec4 normal_modelspace = project.modelMatrix * vec4(vector, 0.0);
vec3 n = normalize(normal_modelspace.xyz * project.commonUnitsPerMeter);
mat3 rotation;
if (project_needs_rotation(geometry.position.xyz, rotation)) {
n = rotation * n;
}
return n;
}
vec4 project_offset_(vec4 offset) {
float dy = offset.y;
vec3 commonUnitsPerWorldUnit = project.commonUnitsPerWorldUnit + project.commonUnitsPerWorldUnit2 * dy;
return vec4(offset.xyz * commonUnitsPerWorldUnit, offset.w);
}
vec2 project_mercator_(vec2 lnglat) {
float x = lnglat.x;
if (project.wrapLongitude) {
x = mod(x + 180., 360.0) - 180.;
}
float y = clamp(lnglat.y, -89.9, 89.9);
return vec2(
radians(x) + PI,
PI + log(tan_fp32(PI * 0.25 + radians(y) * 0.5))
) * WORLD_SCALE;
}
vec3 project_globe_(vec3 lnglatz) {
float lambda = radians(lnglatz.x);
float phi = radians(lnglatz.y);
float cosPhi = cos(phi);
float D = (lnglatz.z / EARTH_RADIUS + 1.0) * GLOBE_RADIUS;
return vec3(
sin(lambda) * cosPhi,
-cos(lambda) * cosPhi,
sin(phi)
) * D;
}
vec4 project_position(vec4 position, vec3 position64Low) {
vec4 position_world = project.modelMatrix * position;
if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR) {
if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
return vec4(
project_mercator_(position_world.xy),
project_size_at_latitude(position_world.z, position_world.y),
position_world.w
);
}
if (project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN) {
position_world.xyz += project.coordinateOrigin;
}
}
if (project.projectionMode == PROJECTION_MODE_GLOBE) {
if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
return vec4(
project_globe_(position_world.xyz),
position_world.w
);
}
}
if (project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET) {
if (project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT) {
if (abs(position_world.y - project.coordinateOrigin.y) > 0.25) {
return vec4(
project_mercator_(position_world.xy) - project.commonOrigin.xy,
project_size(position_world.z),
position_world.w
);
}
}
}
if (project.projectionMode == PROJECTION_MODE_IDENTITY ||
(project.projectionMode == PROJECTION_MODE_WEB_MERCATOR_AUTO_OFFSET &&
(project.coordinateSystem == COORDINATE_SYSTEM_LNGLAT ||
project.coordinateSystem == COORDINATE_SYSTEM_CARTESIAN))) {
position_world.xyz -= project.coordinateOrigin;
}
return project_offset_(position_world) + project_offset_(project.modelMatrix * vec4(position64Low, 0.0));
}
vec4 project_position(vec4 position) {
return project_position(position, ZERO_64_LOW);
}
vec3 project_position(vec3 position, vec3 position64Low) {
vec4 projected_position = project_position(vec4(position, 1.0), position64Low);
return projected_position.xyz;
}
vec3 project_position(vec3 position) {
vec4 projected_position = project_position(vec4(position, 1.0), ZERO_64_LOW);
return projected_position.xyz;
}
vec2 project_position(vec2 position) {
vec4 projected_position = project_position(vec4(position, 0.0, 1.0), ZERO_64_LOW);
return projected_position.xy;
}
vec4 project_common_position_to_clipspace(vec4 position, mat4 viewProjectionMatrix, vec4 center) {
return viewProjectionMatrix * position + center;
}
vec4 project_common_position_to_clipspace(vec4 position) {
return project_common_position_to_clipspace(position, project.viewProjectionMatrix, project.center);
}
vec2 project_pixel_size_to_clipspace(vec2 pixels) {
vec2 offset = pixels / project.viewportSize * project.devicePixelRatio * 2.0;
return offset * project.focalDistance;
}
float project_size_to_pixel(float meters) {
return project_size(meters) * project.scale;
}
float project_size_to_pixel(float size, int unit) {
if (unit == UNIT_METERS) return project_size_to_pixel(size);
if (unit == UNIT_COMMON) return size * project.scale;
return size;
}
float project_pixel_size(float pixels) {
return pixels / project.scale;
}
vec2 project_pixel_size(vec2 pixels) {
return pixels / project.scale;
}
`
);
// dist/shaderlib/project/project.js
var INITIAL_MODULE_OPTIONS = {};
function getUniforms(opts = INITIAL_MODULE_OPTIONS) {
if ("viewport" in opts) {
return getUniformsFromViewport(opts);
}
return {};
}
var project_default = {
name: "project",
dependencies: [import_shadertools.fp32, geometry_default],
source: projectWGSL,
vs: projectGLSL,
getUniforms,
uniformTypes: {
wrapLongitude: "f32",
coordinateSystem: "i32",
commonUnitsPerMeter: "vec3<f32>",
projectionMode: "i32",
scale: "f32",
commonUnitsPerWorldUnit: "vec3<f32>",
commonUnitsPerWorldUnit2: "vec3<f32>",
center: "vec4<f32>",
modelMatrix: "mat4x4<f32>",
viewProjectionMatrix: "mat4x4<f32>",
viewportSize: "vec2<f32>",
devicePixelRatio: "f32",
focalDistance: "f32",
cameraPosition: "vec3<f32>",
coordinateOrigin: "vec3<f32>",
commonOrigin: "vec3<f32>",
pseudoMeters: "f32"
}
// @ts-ignore TODO v9.1
};
// dist/shaderlib/project32/project32.js
var source2 = (
/* wgsl */
`// Define a structure to hold both the clip-space position and the common position.
struct ProjectResult {
clipPosition: vec4<f32>,
commonPosition: vec4<f32>,
};
// This function mimics the GLSL version with the 'out' parameter by returning both values.
fn project_position_to_clipspace_and_commonspace(
position: vec3<f32>,
position64Low: vec3<f32>,
offset: vec3<f32>
) -> ProjectResult {
// Compute the projected position.
let projectedPosition: vec3<f32> = project_position_vec3_f64(position, position64Low);
// Start with the provided offset.
var finalOffset: vec3<f32> = offset;
// Get whether a rotation is needed and the rotation matrix.
let rotationResult = project_needs_rotation(projectedPosition);
// If rotation is needed, update the offset.
if (rotationResult.needsRotation) {
finalOffset = rotationResult.transform * offset;
}
// Compute the common position.
let commonPosition: vec4<f32> = vec4<f32>(projectedPosition + finalOffset, 1.0);
// Convert to clip-space.
let clipPosition: vec4<f32> = project_common_position_to_clipspace(commonPosition);
return ProjectResult(clipPosition, commonPosition);
}
// A convenience overload that returns only the clip-space position.
fn project_position_to_clipspace(
position: vec3<f32>,
position64Low: vec3<f32>,
offset: vec3<f32>
) -> vec4<f32> {
return project_position_to_clipspace_and_commonspace(position, position64Low, offset).clipPosition;
}
`
);
var vs2 = (
/* glsl */
`vec4 project_position_to_clipspace(
vec3 position, vec3 position64Low, vec3 offset, out vec4 commonPosition
) {
vec3 projectedPosition = project_position(position, position64Low);
mat3 rotation;
if (project_needs_rotation(projectedPosition, rotation)) {
// offset is specified as ENU
// when in globe projection, rotate offset so that the ground alighs with the surface of the globe
offset = rotation * offset;
}
commonPosition = vec4(projectedPosition + offset, 1.0);
return project_common_position_to_clipspace(commonPosition);
}
vec4 project_position_to_clipspace(
vec3 position, vec3 position64Low, vec3 offset
) {
vec4 commonPosition;
return project_position_to_clipspace(position, position64Low, offset, commonPosition);
}
`
);
var project32_default = {
name: "project32",
dependencies: [project_default],
source: source2,
vs: vs2
};
// dist/shaderlib/shadow/shadow.js
var import_core3 = require("@math.gl/core");
var import_web_mercator = require("@math.gl/web-mercator");
var uniformBlock2 = (
/* glsl */
`
uniform shadowUniforms {
bool drawShadowMap;
bool useShadowMap;
vec4 color;
highp int lightId;
float lightCount;
mat4 viewProjectionMatrix0;
mat4 viewProjectionMatrix1;
vec4 projectCenter0;
vec4 projectCenter1;
} shadow;
`
);
var vertex = (
/* glsl */
`
const int max_lights = 2;
out vec3 shadow_vPosition[max_lights];
vec4 shadow_setVertexPosition(vec4 position_commonspace) {
mat4 viewProjectionMatrices[max_lights];
viewProjectionMatrices[0] = shadow.viewProjectionMatrix0;
viewProjectionMatrices[1] = shadow.viewProjectionMatrix1;
vec4 projectCenters[max_lights];
projectCenters[0] = shadow.projectCenter0;
projectCenters[1] = shadow.projectCenter1;
if (shadow.drawShadowMap) {
return project_common_position_to_clipspace(position_commonspace, viewProjectionMatrices[shadow.lightId], projectCenters[shadow.lightId]);
}
if (shadow.useShadowMap) {
for (int i = 0; i < max_lights; i++) {
if(i < int(shadow.lightCount)) {
vec4 shadowMap_position = project_common_position_to_clipspace(position_commonspace, viewProjectionMatrices[i], projectCenters[i]);
shadow_vPosition[i] = (shadowMap_position.xyz / shadowMap_position.w + 1.0) / 2.0;
}
}
}
return gl_Position;
}
`
);
var vs3 = `
${uniformBlock2}
${vertex}
`;
var fragment = (
/* glsl */
`
const int max_lights = 2;
uniform sampler2D shadow_uShadowMap0;
uniform sampler2D shadow_uShadowMap1;
in vec3 shadow_vPosition[max_lights];
const vec4 bitPackShift = vec4(1.0, 255.0, 65025.0, 16581375.0);
const vec4 bitUnpackShift = 1.0 / bitPackShift;
const vec4 bitMask = vec4(1.0 / 255.0, 1.0 / 255.0, 1.0 / 255.0, 0.0);
float shadow_getShadowWeight(vec3 position, sampler2D shadowMap) {
vec4 rgbaDepth = texture(shadowMap, position.xy);
float z = dot(rgbaDepth, bitUnpackShift);
return smoothstep(0.001, 0.01, position.z - z);
}
vec4 shadow_filterShadowColor(vec4 color) {
if (shadow.drawShadowMap) {
vec4 rgbaDepth = fract(gl_FragCoord.z * bitPackShift);
rgbaDepth -= rgbaDepth.gbaa * bitMask;
return rgbaDepth;
}
if (shadow.useShadowMap) {
float shadowAlpha = 0.0;
shadowAlpha += shadow_getShadowWeight(shadow_vPosition[0], shadow_uShadowMap0);
if(shadow.lightCount > 1.0) {
shadowAlpha += shadow_getShadowWeight(shadow_vPosition[1], shadow_uShadowMap1);
}
shadowAlpha *= shadow.color.a / shadow.lightCount;
float blendedAlpha = shadowAlpha + color.a * (1.0 - shadowAlpha);
return vec4(
mix(color.rgb, shadow.color.rgb, shadowAlpha / blendedAlpha),
blendedAlpha
);
}
return color;
}
`
);
var fs2 = `
${uniformBlock2}
${fragment}
`;
var getMemoizedViewportCenterPosition = memoize(getViewportCenterPosition);
var getMemoizedViewProjectionMatrices = memoize(getViewProjectionMatrices);
var DEFAULT_SHADOW_COLOR = [0, 0, 0, 1];
var VECTOR_TO_POINT_MATRIX2 = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0];
function screenToCommonSpace(xyz, pixelUnprojectionMatrix) {
const [x, y, z] = xyz;
const coord = (0, import_web_mercator.pixelsToWorld)([x, y, z], pixelUnprojectionMatrix);
if (Number.isFinite(z)) {
return coord;
}
return [coord[0], coord[1], 0];
}
function getViewportCenterPosition({ viewport, center }) {
return new import_core3.Matrix4(viewport.viewProjectionMatrix).invert().transform(center);
}
function getViewProjectionMatrices({ viewport, shadowMatrices }) {
const projectionMatrices = [];
const pixelUnprojectionMatrix = viewport.pixelUnprojectionMatrix;
const farZ = viewport.isGeospatial ? void 0 : 1;
const corners = [
[0, 0, farZ],
// top left ground
[viewport.width, 0, farZ],
// top right ground
[0, viewport.height, farZ],
// bottom left ground
[viewport.width, viewport.height, farZ],
// bottom right ground
[0, 0, -1],
// top left near
[viewport.width, 0, -1],
// top right near
[0, viewport.height, -1],
// bottom left near
[viewport.width, viewport.height, -1]
// bottom right near
].map((pixel) => (
// @ts-expect-error z may be undefined
screenToCommonSpace(pixel, pixelUnprojectionMatrix)
));
for (const shadowMatrix of shadowMatrices) {
const viewMatrix2 = shadowMatrix.clone().translate(new import_core3.Vector3(viewport.center).negate());
const positions = corners.map((corner) => viewMatrix2.transform(corner));
const projectionMatrix = new import_core3.Matrix4().ortho({
left: Math.min(...positions.map((position) => position[0])),
right: Math.max(...positions.map((position) => position[0])),
bottom: Math.min(...positions.map((position) => position[1])),
top: Math.max(...positions.map((position) => position[1])),
near: Math.min(...positions.map((position) => -position[2])),
far: Math.max(...positions.map((position) => -position[2]))
});
projectionMatrices.push(projectionMatrix.multiplyRight(shadowMatrix));
}
return projectionMatrices;
}
function createShadowUniforms(opts) {
const { shadowEnabled = true, project: projectProps } = opts;
if (!shadowEnabled || !projectProps || !opts.shadowMatrices || !opts.shadowMatrices.length) {
return {
drawShadowMap: false,
useShadowMap: false,
shadow_uShadowMap0: opts.dummyShadowMap,
shadow_uShadowMap1: opts.dummyShadowMap
};
}
const projectUniforms = project_default.getUniforms(projectProps);
const center = getMemoizedViewportCenterPosition({
viewport: projectProps.viewport,
center: projectUniforms.center
});
const projectCenters = [];
const viewProjectionMatrices = getMemoizedViewProjectionMatrices({
shadowMatrices: opts.shadowMatrices,
viewport: projectProps.viewport
}).slice();
for (let i = 0; i < opts.shadowMatrices.length; i++) {
const viewProjectionMatrix = viewProjectionMatrices[i];
const viewProjectionMatrixCentered = viewProjectionMatrix.clone().translate(new import_core3.Vector3(projectProps.viewport.center).negate());
if (projectUniforms.coordinateSystem === COORDINATE_SYSTEM.LNGLAT && projectUniforms.projectionMode === PROJECTION_MODE.WEB_MERCATOR) {
viewProjectionMatrices[i] = viewProjectionMatrixCentered;
projectCenters[i] = center;
} else {
viewProjectionMatrices[i] = viewProjectionMatrix.clone().multiplyRight(VECTOR_TO_POINT_MATRIX2);
projectCenters[i] = viewProjectionMatrixCentered.transform(center);
}
}
const uniforms = {
drawShadowMap: Boolean(opts.drawToShadowMap),
useShadowMap: opts.shadowMaps ? opts.shadowMaps.length > 0 : false,
color: opts.shadowColor || DEFAULT_SHADOW_COLOR,
lightId: opts.shadowLightId || 0,
lightCount: opts.shadowMatrices.length,
shadow_uShadowMap0: opts.dummyShadowMap,
shadow_uShadowMap1: opts.dummyShadowMap
};
for (let i = 0; i < viewProjectionMatrices.length; i++) {
uniforms[`viewProjectionMatrix${i}`] = viewProjectionMatrices[i];
uniforms[`projectCenter${i}`] = projectCenters[i];
}
for (let i = 0; i < 2; i++) {
uniforms[`shadow_uShadowMap${i}`] = opts.shadowMaps && opts.shadowMaps[i] || opts.dummyShadowMap;
}
return uniforms;
}
var shadow_default = {
name: "shadow",
dependencies: [project_default],
vs: vs3,
fs: fs2,
inject: {
"vs:DECKGL_FILTER_GL_POSITION": `