diff --git a/modules/layers/src/icon-layer/icon-layer-uniforms.ts b/modules/layers/src/icon-layer/icon-layer-uniforms.ts index 82620f24fd4..51a387c5c47 100644 --- a/modules/layers/src/icon-layer/icon-layer-uniforms.ts +++ b/modules/layers/src/icon-layer/icon-layer-uniforms.ts @@ -11,7 +11,6 @@ uniform iconUniforms { vec2 iconsTextureDim; float sizeMinPixels; float sizeMaxPixels; - bool billboard; highp int sizeUnits; float alphaCutoff; } icon; @@ -26,7 +25,6 @@ type IconUniformProps = { iconsTextureDim: [number, number]; sizeMinPixels: number; sizeMaxPixels: number; - billboard: boolean; sizeUnits: number; alphaCutoff: number; }; @@ -42,7 +40,6 @@ export const iconUniforms = { iconsTextureDim: 'vec2', sizeMinPixels: 'f32', sizeMaxPixels: 'f32', - billboard: 'f32', sizeUnits: 'i32', alphaCutoff: 'f32' } diff --git a/modules/layers/src/icon-layer/icon-layer-vertex.glsl.ts b/modules/layers/src/icon-layer/icon-layer-vertex.glsl.ts index 9146a336050..a806be5d3da 100644 --- a/modules/layers/src/icon-layer/icon-layer-vertex.glsl.ts +++ b/modules/layers/src/icon-layer/icon-layer-vertex.glsl.ts @@ -18,6 +18,7 @@ in vec4 instanceIconFrames; in float instanceColorModes; in vec2 instanceOffsets; in vec2 instancePixelOffset; +in float instanceBillboards; out float vColorMode; out vec4 vColor; @@ -56,7 +57,7 @@ void main(void) { pixelOffset += instancePixelOffset; pixelOffset.y *= -1.0; - if (icon.billboard) { + if (instanceBillboards > 0.0) { gl_Position = project_position_to_clipspace(instancePositions, instancePositions64Low, vec3(0.0), geometry.position); DECKGL_FILTER_GL_POSITION(gl_Position, geometry); vec3 offset = vec3(pixelOffset, 0.0); diff --git a/modules/layers/src/icon-layer/icon-layer.ts b/modules/layers/src/icon-layer/icon-layer.ts index eaf0553cda8..e1b1f59c518 100644 --- a/modules/layers/src/icon-layer/icon-layer.ts +++ b/modules/layers/src/icon-layer/icon-layer.ts @@ -51,10 +51,6 @@ type _IconLayerProps = { * The maximum size in pixels. When using non-pixel `sizeUnits`, this prop can be used to prevent the icon from getting too big when zoomed in. */ sizeMaxPixels?: number; - /** If `true`, the icon always faces camera. Otherwise the icon faces up (z) - * @default true - */ - billboard?: boolean; /** * Discard pixels whose opacity is below this threshold. * A discarded pixel would create a "hole" in the icon that is not considered part of the object. @@ -86,6 +82,10 @@ type _IconLayerProps = { * @default [0, 0] */ getPixelOffset?: Accessor; + /** Icon billboard accessor. If `true`, the icon always faces camera. Otherwise the icon faces up (z) + * @default true + */ + getBillboard?: Accessor; /** * Callback called if the attempt to fetch an icon returned by `getIcon` fails. */ @@ -103,7 +103,6 @@ const defaultProps: DefaultProps = { iconAtlas: {type: 'image', value: null, async: true}, iconMapping: {type: 'object', value: {}, async: true}, sizeScale: {type: 'number', value: 1, min: 0}, - billboard: true, sizeUnits: 'pixels', sizeMinPixels: {type: 'number', min: 0, value: 0}, // min point radius in pixels sizeMaxPixels: {type: 'number', min: 0, value: Number.MAX_SAFE_INTEGER}, // max point radius in pixels @@ -115,6 +114,7 @@ const defaultProps: DefaultProps = { getSize: {type: 'accessor', value: 1}, getAngle: {type: 'accessor', value: 0}, getPixelOffset: {type: 'accessor', value: [0, 0]}, + getBillboard: {type: 'accessor', value: true}, onIconError: {type: 'function', value: null, optional: true}, @@ -196,6 +196,14 @@ export default class IconLayer extends size: 2, transition: true, accessor: 'getPixelOffset' + }, + instanceBillboards: { + size: 1, + type: 'uint8', + accessor: 'getBillboard', + defaultValue: 1, + // eslint-disable-next-line @typescript-eslint/unbound-method + transform: this.getInstanceBillboard } }); /* eslint-enable max-len */ @@ -257,7 +265,7 @@ export default class IconLayer extends } draw({uniforms}): void { - const {sizeScale, sizeMinPixels, sizeMaxPixels, sizeUnits, billboard, alphaCutoff} = this.props; + const {sizeScale, sizeMinPixels, sizeMaxPixels, sizeUnits, alphaCutoff} = this.props; const {iconManager} = this.state; const iconsTexture = iconManager.getTexture(); @@ -270,7 +278,6 @@ export default class IconLayer extends sizeScale, sizeMinPixels, sizeMaxPixels, - billboard, alphaCutoff }; @@ -335,4 +342,8 @@ export default class IconLayer extends const {x, y, width, height} = this.state.iconManager.getIconMapping(icon); return [x, y, width, height]; } + + protected getInstanceBillboard(billboard: boolean): number { + return billboard ? 1 : 0; + } }