From 100e12084a852355460e449a44711724cc97b943 Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Fri, 27 Sep 2024 17:44:17 -0700 Subject: [PATCH 1/9] generic module props handling in Layer class --- .../src/effects/lighting/lighting-effect.ts | 28 +++++-- modules/core/src/lib/layer.ts | 82 +------------------ modules/core/src/passes/layers-pass.ts | 67 +++++++++++---- modules/core/src/passes/pick-layers-pass.ts | 2 +- modules/core/src/passes/shadow-pass.ts | 7 +- modules/core/src/shaderlib/shadow/shadow.ts | 32 +++----- .../collision-filter-effect.ts | 37 ++++++--- .../collision-filter-extension.ts | 16 +--- .../collision-filter/collision-filter-pass.ts | 6 +- .../src/collision-filter/shader-module.ts | 2 +- modules/extensions/src/mask/mask-effect.ts | 16 ++-- modules/extensions/src/mask/mask-extension.ts | 2 +- modules/extensions/src/mask/shader-module.ts | 2 +- .../extensions/src/terrain/shader-module.ts | 7 +- .../extensions/src/terrain/terrain-effect.ts | 43 ++++++---- .../src/terrain/terrain-extension.ts | 2 +- 16 files changed, 163 insertions(+), 188 deletions(-) diff --git a/modules/core/src/effects/lighting/lighting-effect.ts b/modules/core/src/effects/lighting/lighting-effect.ts index f11e82d5a90..0cc6470f8f0 100644 --- a/modules/core/src/effects/lighting/lighting-effect.ts +++ b/modules/core/src/effects/lighting/lighting-effect.ts @@ -13,7 +13,7 @@ import shadow from '../../shaderlib/shadow/shadow'; import type Layer from '../../lib/layer'; import type {Effect, EffectContext, PreRenderOptions} from '../../lib/effect'; -import {LightingProps} from '@luma.gl/shadertools'; +import type Viewport from '../../viewports/viewport'; const DEFAULT_AMBIENT_LIGHT_PROPS = { color: [255, 255, 255] as [number, number, number], @@ -118,23 +118,26 @@ export default class LightingEffect implements Effect { onViewportActive, views, moduleParameters: { - shadowLightId: i, - dummyShadowMap: this.dummyShadowMap, - shadowMatrices: this.shadowMatrices + shadow: { + shadowLightId: i, + dummyShadowMap: this.dummyShadowMap, + shadowMatrices: this.shadowMatrices + } } }); } } getModuleParameters(layer: Layer) { - const parameters: { - lightSources?: LightingProps; + const shadowProps: { + viewport?: Viewport; shadowMaps?: Texture[]; dummyShadowMap?: Texture | null; shadowColor?: [number, number, number, number]; shadowMatrices?: Matrix4[]; } = this.shadow ? { + viewport: layer.context.viewport, shadowMaps: this.shadowPasses.map(shadowPass => shadowPass.getShadowMap()), dummyShadowMap: this.dummyShadowMap, shadowColor: this.shadowColor, @@ -144,7 +147,7 @@ export default class LightingEffect implements Effect { // when not rendering to screen, turn off lighting by adding empty light source object // lights shader module relies on the `lightSources` to turn on/off lighting - parameters.lightSources = { + const lightingProps = { enabled: true, ambientLight: this.ambientLight, directionalLights: this.directionalLights.map(directionalLight => @@ -152,8 +155,15 @@ export default class LightingEffect implements Effect { ), pointLights: this.pointLights.map(pointLight => pointLight.getProjectedLight({layer})) }; - - return parameters; + // @ts-expect-error material is not a Layer prop + const materialProps = layer.props.material; + + return { + shadow: shadowProps, + lighting: lightingProps, + phongMaterial: materialProps, + gouraudMaterial: materialProps + }; } cleanup(context: EffectContext): void { diff --git a/modules/core/src/lib/layer.ts b/modules/core/src/lib/layer.ts index bee85e0f9ee..266dadfa9e9 100644 --- a/modules/core/src/lib/layer.ts +++ b/modules/core/src/lib/layer.ts @@ -39,7 +39,6 @@ import type {LayerContext} from './layer-manager'; import type {BinaryAttribute} from './attribute/attribute'; import {RenderPass} from '@luma.gl/core'; import {PickingProps} from '@luma.gl/shadertools'; -import {ProjectProps} from '../shaderlib/project/viewport-uniforms'; const TRACE_CHANGE_FLAG = 'layer.changeFlag'; const TRACE_INITIALIZE = 'layer.initialize'; @@ -1061,87 +1060,8 @@ export default abstract class Layer extends Component< try { // TODO/ib - hack move to luma Model.draw if (moduleParameters) { - const {isActive, isAttribute} = moduleParameters.picking; - const {viewport, devicePixelRatio, coordinateSystem, coordinateOrigin} = moduleParameters; - // @ts-expect-error material is not a Layer prop - const {material, modelMatrix} = this.props; - this.setModuleParameters({}); - - const { - // mask - maskChannels, - maskMap, - maskSources, - // shadow - shadowEnabled, - drawToShadowMap, - shadowMaps, - dummyShadowMap, - shadowColor, - shadowMatrices, - shadowLightId, - // terrain - picking, - heightMap, - heightMapBounds, - dummyHeightMap, - terrainCover, - drawToTerrainHeightMap, - useTerrainHeightMap, - terrainSkipRender, - // lighting - lightSources - } = moduleParameters; - - const maskProps = { - maskChannels, - maskMap, - maskSources - }; - - const shadowProps = { - viewport, - shadowEnabled, - drawToShadowMap, - shadowMaps, - dummyShadowMap, - shadowColor, - shadowMatrices, - shadowLightId - }; - const terrainProps = { - viewport, - picking, - heightMap, - heightMapBounds, - dummyHeightMap, - terrainCover, - drawToTerrainHeightMap, - useTerrainHeightMap, - terrainSkipRender - }; - - const projectProps = { - viewport, - devicePixelRatio, - modelMatrix, - coordinateSystem, - coordinateOrigin - } as ProjectProps; - - this.setShaderModuleProps({ - // TODO Revisit whether this is necessary once all layers ported to UBO - mask: maskProps, - shadow: shadowProps, - terrain: terrainProps, - layer: {opacity}, - lighting: lightSources, - phongMaterial: material, - gouraudMaterial: material, - picking: {isActive, isAttribute} as const satisfies PickingProps, - project: projectProps - }); + this.setShaderModuleProps(moduleParameters); } // Apply polygon offset to avoid z-fighting diff --git a/modules/core/src/passes/layers-pass.ts b/modules/core/src/passes/layers-pass.ts index 9ddc98fa618..b523963d255 100644 --- a/modules/core/src/passes/layers-pass.ts +++ b/modules/core/src/passes/layers-pass.ts @@ -10,6 +10,9 @@ import type Viewport from '../viewports/viewport'; import type View from '../views/view'; import type Layer from '../lib/layer'; import type {Effect} from '../lib/effect'; +import type {ProjectProps} from '../shaderlib/project/viewport-uniforms'; +import type {LayerProps} from '../shaderlib/misc/layer-uniforms'; +import type {PickingProps} from '@luma.gl/shadertools'; export type Rect = {x: number; y: number; width: number; height: number}; @@ -263,7 +266,12 @@ export default class LayersPass extends Pass { this._lastRenderIndex = Math.max(this._lastRenderIndex, layerRenderIndex); // overwrite layer.context.viewport with the sub viewport - moduleParameters.viewport = viewport; + for (const moduleName in moduleParameters) { + const moduleProps = moduleParameters[moduleName]; + if (moduleProps && typeof moduleProps === 'object' && 'viewport' in moduleProps) { + moduleProps.viewport = viewport; + } + } // TODO v9 - we are sending renderPass both as a parameter and through the context. // Long-term, it is likely better not to have user defined layer methods have to access @@ -349,27 +357,36 @@ export default class LayersPass extends Pass { ): any { // @ts-expect-error TODO - assuming WebGL context const devicePixelRatio = this.device.canvasContext.cssToDeviceRatio(); - - const moduleParameters = Object.assign( - Object.create(layer.internalState?.propsInTransition || layer.props), - { - autoWrapLongitude: layer.wrapLongitude, + const layerProps = layer.internalState?.propsInTransition || layer.props; + + const moduleParameters = { + layer: { + opacity: layerProps.opacity + } satisfies LayerProps, + picking: { + isActive: false + } satisfies PickingProps, + project: { viewport: layer.context.viewport, - mousePosition: layer.context.mousePosition, - picking: { - isActive: 0 - }, - devicePixelRatio - } - ); + devicePixelRatio, + modelMatrix: layerProps.modelMatrix, + coordinateSystem: layerProps.coordinateSystem, + coordinateOrigin: layerProps.coordinateOrigin, + autoWrapLongitude: layerProps.wrapLongitude + } satisfies ProjectProps + }; if (effects) { for (const effect of effects) { - Object.assign(moduleParameters, effect.getModuleParameters?.(layer)); + mergeModuleParameters(moduleParameters, effect.getModuleParameters?.(layer)); } } - return Object.assign(moduleParameters, this.getModuleParameters(layer, effects), overrides); + return mergeModuleParameters( + moduleParameters, + this.getModuleParameters(layer, effects), + overrides + ); } } @@ -435,7 +452,7 @@ function getGLViewport( } ): [number, number, number, number] { const pixelRatio = - (moduleParameters && moduleParameters.devicePixelRatio) || + moduleParameters?.project?.devicePixelRatio ?? // @ts-expect-error TODO - assuming WebGL context device.canvasContext.cssToDeviceRatio(); @@ -453,3 +470,21 @@ function getGLViewport( dimensions.height * pixelRatio ]; } + +function mergeModuleParameters( + target: Record, + ...sources: Record[] +): Record { + for (const source of sources) { + if (source) { + for (const key in source) { + if (target[key]) { + Object.assign(target[key], source[key]); + } else { + target[key] = source[key]; + } + } + } + } + return target; +} diff --git a/modules/core/src/passes/pick-layers-pass.ts b/modules/core/src/passes/pick-layers-pass.ts index 940564413dd..a5bded2c1a9 100644 --- a/modules/core/src/passes/pick-layers-pass.ts +++ b/modules/core/src/passes/pick-layers-pass.ts @@ -121,7 +121,7 @@ export default class PickLayersPass extends LayersPass { isActive: 1, isAttribute: this.pickZ }, - lightSources: {enabled: false} + lighting: {enabled: false} }; } diff --git a/modules/core/src/passes/shadow-pass.ts b/modules/core/src/passes/shadow-pass.ts index 3ab64599e21..d7857bbb101 100644 --- a/modules/core/src/passes/shadow-pass.ts +++ b/modules/core/src/passes/shadow-pass.ts @@ -85,9 +85,12 @@ export default class ShadowPass extends LayersPass { return layer.props.shadowEnabled !== false; } - getModuleParameters() { + getModuleParameters(layer: Layer) { return { - drawToShadowMap: true + shadow: { + viewport: layer.context.viewport, + drawToShadowMap: true + } }; } } diff --git a/modules/core/src/shaderlib/shadow/shadow.ts b/modules/core/src/shaderlib/shadow/shadow.ts index 92e525d1342..a10c1253708 100644 --- a/modules/core/src/shaderlib/shadow/shadow.ts +++ b/modules/core/src/shaderlib/shadow/shadow.ts @@ -206,34 +206,34 @@ function getViewProjectionMatrices({ // eslint-disable-next-line complexity function createShadowUniforms( - opts: ShadowModuleProps + opts: Partial ): ShadowModuleBindings & ShadowModuleUniforms { const {shadowEnabled = true} = opts; if (!shadowEnabled || !opts.shadowMatrices || !opts.shadowMatrices.length) { return { drawShadowMap: false, useShadowMap: false, - shadow_uShadowMap0: opts.dummyShadowMap, - shadow_uShadowMap1: opts.dummyShadowMap + shadow_uShadowMap0: opts.dummyShadowMap!, + shadow_uShadowMap1: opts.dummyShadowMap! }; } const projectUniforms = project.getUniforms(opts) as ProjectUniforms; const center = getMemoizedViewportCenterPosition({ - viewport: opts.viewport, + viewport: opts.viewport!, center: projectUniforms.center }); const projectCenters: NumericArray[] = []; const viewProjectionMatrices = getMemoizedViewProjectionMatrices({ shadowMatrices: opts.shadowMatrices, - viewport: opts.viewport + viewport: opts.viewport! }).slice(); for (let i = 0; i < opts.shadowMatrices.length; i++) { const viewProjectionMatrix = viewProjectionMatrices[i]; const viewProjectionMatrixCentered = viewProjectionMatrix .clone() - .translate(new Vector3(opts.viewport.center).negate()); + .translate(new Vector3(opts.viewport!.center).negate()); if ( projectUniforms.coordinateSystem === COORDINATE_SYSTEM.LNGLAT && @@ -249,14 +249,14 @@ function createShadowUniforms( } } - const uniforms = { + const uniforms: ShadowModuleUniforms & ShadowModuleBindings = { 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 + shadow_uShadowMap0: opts.dummyShadowMap!, + shadow_uShadowMap1: opts.dummyShadowMap! }; for (let i = 0; i < viewProjectionMatrices.length; i++) { @@ -284,19 +284,7 @@ export default { color = shadow_filterShadowColor(color); ` }, - getUniforms: ( - opts: {drawToShadowMap?: boolean; shadowMaps?: unknown[]} = {}, - context: any = {} - ) => { - if ( - 'viewport' in opts && - (opts.drawToShadowMap || (opts.shadowMaps && opts.shadowMaps.length > 0)) - ) { - // @ts-expect-error if opts.viewport is defined, context should contain the project module's uniforms - return createShadowUniforms(opts, context); - } - return {}; - }, + getUniforms: createShadowUniforms, uniformTypes: { drawShadowMap: 'f32', useShadowMap: 'f32', diff --git a/modules/extensions/src/collision-filter/collision-filter-effect.ts b/modules/extensions/src/collision-filter/collision-filter-effect.ts index 6153ca822f5..d3a79ef129d 100644 --- a/modules/extensions/src/collision-filter/collision-filter-effect.ts +++ b/modules/extensions/src/collision-filter/collision-filter-effect.ts @@ -10,10 +10,8 @@ import CollisionFilterPass from './collision-filter-pass'; import {MaskPreRenderStats} from '../mask/mask-effect'; // import {debugFBO} from '../utils/debug'; -type CollisionFilterExtensionProps = { - collisionTestProps?: {}; - collisionGroup: string; -}; +import type {CollisionFilterExtensionProps} from './collision-filter-extension'; +import type {CollisionModuleProps} from './shader-module'; // Factor by which to downscale Collision FBO relative to canvas const DOWNSCALE = 2; @@ -160,10 +158,15 @@ export default class CollisionFilterEffect implements Effect { onViewportActive, views, moduleParameters: { - // To avoid feedback loop forming between Framebuffer and active Texture. - dummyCollisionMap: this.dummyCollisionMap, - // @ts-expect-error TODO - assuming WebGL context - devicePixelRatio: collisionFBO.device.canvasContext.getDevicePixelRatio() / DOWNSCALE + collision: { + enabled: true, + // To avoid feedback loop forming between Framebuffer and active Texture. + dummyCollisionMap: this.dummyCollisionMap + }, + project: { + // @ts-expect-error TODO - assuming WebGL context + devicePixelRatio: collisionFBO.device.canvasContext.getDevicePixelRatio() / DOWNSCALE + } } }); } @@ -179,7 +182,7 @@ export default class CollisionFilterEffect implements Effect { ): Record { const channelMap = {}; for (const layer of collisionLayers) { - const {collisionGroup} = layer.props; + const collisionGroup = layer.props.collisionGroup!; let channelInfo = channelMap[collisionGroup]; if (!channelInfo) { channelInfo = {collisionGroup, layers: [], layerBounds: [], allLayersLoaded: true}; @@ -211,12 +214,20 @@ export default class CollisionFilterEffect implements Effect { } getModuleParameters(layer: Layer): { - collisionFBO: Framebuffer; - dummyCollisionMap: Texture; + collision: CollisionModuleProps; } { - const {collisionGroup} = (layer as Layer).props; + const {collisionGroup, collisionEnabled} = (layer as Layer) + .props; const {collisionFBOs, dummyCollisionMap} = this; - return {collisionFBO: collisionFBOs[collisionGroup], dummyCollisionMap: dummyCollisionMap!}; + const collisionFBO = collisionFBOs[collisionGroup!]; + const enabled = collisionEnabled && Boolean(collisionFBO); + return { + collision: { + enabled, + collisionFBO, + dummyCollisionMap: dummyCollisionMap! + } + }; } cleanup(): void { diff --git a/modules/extensions/src/collision-filter/collision-filter-extension.ts b/modules/extensions/src/collision-filter/collision-filter-extension.ts index d29a8011f26..b4e1ba31493 100644 --- a/modules/extensions/src/collision-filter/collision-filter-extension.ts +++ b/modules/extensions/src/collision-filter/collision-filter-extension.ts @@ -3,7 +3,7 @@ // Copyright (c) vis.gl contributors import {Accessor, Layer, LayerContext, LayerExtension} from '@deck.gl/core'; -import collision, {CollisionModuleProps} from './shader-module'; +import collision from './shader-module'; import CollisionFilterEffect from './collision-filter-effect'; const defaultProps = { @@ -47,23 +47,11 @@ export default class CollisionFilterExtension extends LayerExtension { /* eslint-disable camelcase */ draw(this: Layer, {moduleParameters}: any) { - const {collisionEnabled} = this.props; - const {collisionFBO, drawToCollisionMap, dummyCollisionMap} = moduleParameters; - const enabled = collisionEnabled && Boolean(collisionFBO); - - if (drawToCollisionMap) { + if (moduleParameters.collision?.drawToCollisionMap) { // Override any props with those defined in collisionTestProps // @ts-ignore this.props = this.clone(this.props.collisionTestProps).props; } - - const collisionProps: CollisionModuleProps = { - enabled, - collisionFBO, - drawToCollisionMap, - dummyCollisionMap - }; - this.setShaderModuleProps({collision: collisionProps}); } initializeState( diff --git a/modules/extensions/src/collision-filter/collision-filter-pass.ts b/modules/extensions/src/collision-filter/collision-filter-pass.ts index 9ccdf667c1d..cc197eaa183 100644 --- a/modules/extensions/src/collision-filter/collision-filter-pass.ts +++ b/modules/extensions/src/collision-filter/collision-filter-pass.ts @@ -23,12 +23,14 @@ export default class CollisionFilterPass extends LayersPass { getModuleParameters() { // Draw picking colors into collision FBO return { - drawToCollisionMap: true, + collision: { + drawToCollisionMap: true + }, picking: { isActive: 1, isAttribute: false }, - lightSources: {enabled: false} + lighting: {enabled: false} }; } } diff --git a/modules/extensions/src/collision-filter/shader-module.ts b/modules/extensions/src/collision-filter/shader-module.ts index 77a9a7c680b..1e1658d5fe8 100644 --- a/modules/extensions/src/collision-filter/shader-module.ts +++ b/modules/extensions/src/collision-filter/shader-module.ts @@ -72,7 +72,7 @@ const inject = { collision_fade = collision_isVisible(collision_texCoords, geometry.pickingColor / 255.0); if (collision_fade < 0.0001) { // Position outside clip space bounds to discard - position = vec4(0.0, 0.0, 2.0, 1.0); + // position = vec4(0.0, 0.0, 2.0, 1.0); } } `, diff --git a/modules/extensions/src/mask/mask-effect.ts b/modules/extensions/src/mask/mask-effect.ts index 9b9a19522c9..334822eb712 100644 --- a/modules/extensions/src/mask/mask-effect.ts +++ b/modules/extensions/src/mask/mask-effect.ts @@ -191,7 +191,9 @@ export default class MaskEffect implements Effect { onViewportActive, views, moduleParameters: { - devicePixelRatio: 1 + project: { + devicePixelRatio: 1 + } } }); @@ -262,12 +264,16 @@ export default class MaskEffect implements Effect { } getModuleParameters(): { - maskMap: Texture; - maskChannels: Record | null; + mask: { + maskMap: Texture; + maskChannels: Record | null; + }; } { return { - maskMap: this.masks ? this.maskMap! : this.dummyMaskMap!, - maskChannels: this.masks + mask: { + maskMap: this.masks ? this.maskMap! : this.dummyMaskMap!, + maskChannels: this.masks + } }; } diff --git a/modules/extensions/src/mask/mask-extension.ts b/modules/extensions/src/mask/mask-extension.ts index b42416d7182..b3a08a5f2c8 100644 --- a/modules/extensions/src/mask/mask-extension.ts +++ b/modules/extensions/src/mask/mask-extension.ts @@ -57,7 +57,7 @@ export default class MaskExtension extends LayerExtension { const maskProps = {} as MaskProps; maskProps.maskByInstance = Boolean(this.state.maskByInstance); const {maskId, maskInverted} = this.props; - const {maskChannels} = moduleParameters; + const {maskChannels} = moduleParameters.mask || {}; const {viewport} = context; if (maskChannels && maskChannels[maskId]) { const {index, bounds, coordinateOrigin: fromCoordinateOrigin} = maskChannels[maskId]; diff --git a/modules/extensions/src/mask/shader-module.ts b/modules/extensions/src/mask/shader-module.ts index 2283adc8934..df4e4e5b78e 100644 --- a/modules/extensions/src/mask/shader-module.ts +++ b/modules/extensions/src/mask/shader-module.ts @@ -81,7 +81,7 @@ in vec2 mask_texCoords; // Debug: show extent of render target // fragColor = vec4(mask_texCoords, 0.0, 1.0); - fragColor = texture(mask_texture, mask_texCoords); + // fragColor = texture(mask_texture, mask_texCoords); if (!mask) discard; } diff --git a/modules/extensions/src/terrain/shader-module.ts b/modules/extensions/src/terrain/shader-module.ts index f12a7baa978..bdb39a4fb2b 100644 --- a/modules/extensions/src/terrain/shader-module.ts +++ b/modules/extensions/src/terrain/shader-module.ts @@ -14,7 +14,7 @@ import type {TerrainCover} from './terrain-cover'; /** Module parameters expected by the terrain shader module */ export type TerrainModuleProps = { viewport: Viewport; - picking: {isActive?: boolean}; + isPicking: boolean; heightMap: Texture | null; heightMapBounds?: Bounds | null; dummyHeightMap: Texture; @@ -146,12 +146,11 @@ if ((terrain.mode == TERRAIN_MODE_USE_COVER) || (terrain.mode == TERRAIN_MODE_US bounds = heightMapBounds!; } else if (terrainCover) { // This is a terrain layer - const isPicking = opts.picking?.isActive; - const fbo = isPicking + const fbo = opts.isPicking ? terrainCover.getPickingFramebuffer() : terrainCover.getRenderFramebuffer(); sampler = fbo?.colorAttachments[0].texture; - if (isPicking) { + if (opts.isPicking) { // Never render the layer itself in picking pass mode = TERRAIN_MODE.SKIP; } diff --git a/modules/extensions/src/terrain/terrain-effect.ts b/modules/extensions/src/terrain/terrain-effect.ts index 44c9381f5ad..3dab88c3e59 100644 --- a/modules/extensions/src/terrain/terrain-effect.ts +++ b/modules/extensions/src/terrain/terrain-effect.ts @@ -86,18 +86,21 @@ export class TerrainEffect implements Effect { this._updateTerrainCovers(terrainLayers, drapeLayers, viewport, opts); } - getModuleParameters(layer: Layer): Omit { + getModuleParameters(layer: Layer): {terrain: TerrainModuleProps} { const {viewport} = layer.context; const {terrainDrawMode} = layer.state; return { - viewport, - heightMap: this.heightMap?.getRenderFramebuffer()?.colorAttachments[0].texture || null, - heightMapBounds: this.heightMap?.bounds, - dummyHeightMap: this.dummyHeightMap!, - terrainCover: this.isDrapingEnabled ? this.terrainCovers.get(layer.id) : null, - useTerrainHeightMap: terrainDrawMode === 'offset', - terrainSkipRender: terrainDrawMode === 'drape' || !layer.props.operation.includes('draw') + terrain: { + viewport, + isPicking: this.isPicking, + heightMap: this.heightMap?.getRenderFramebuffer()?.colorAttachments[0].texture || null, + heightMapBounds: this.heightMap?.bounds, + dummyHeightMap: this.dummyHeightMap!, + terrainCover: this.isDrapingEnabled ? this.terrainCovers.get(layer.id) : null, + useTerrainHeightMap: terrainDrawMode === 'offset', + terrainSkipRender: terrainDrawMode === 'drape' || !layer.props.operation.includes('draw') + } }; } @@ -135,10 +138,15 @@ export class TerrainEffect implements Effect { ...opts, layers: terrainLayers, moduleParameters: { - heightMapBounds: this.heightMap.bounds, - dummyHeightMap: this.dummyHeightMap, - devicePixelRatio: 1, - drawToTerrainHeightMap: true + terrain: { + viewport, + heightMapBounds: this.heightMap.bounds, + dummyHeightMap: this.dummyHeightMap, + drawToTerrainHeightMap: true + }, + project: { + devicePixelRatio: 1 + } } }); } @@ -193,9 +201,14 @@ export class TerrainEffect implements Effect { ...opts, layers: drapeLayers, moduleParameters: { - dummyHeightMap: this.dummyHeightMap, - terrainSkipRender: false, - devicePixelRatio: 1 + terrain: { + viewport, + dummyHeightMap: this.dummyHeightMap, + terrainSkipRender: false + }, + project: { + devicePixelRatio: 1 + } } }); diff --git a/modules/extensions/src/terrain/terrain-extension.ts b/modules/extensions/src/terrain/terrain-extension.ts index 95c6bcd5e5e..d08e09d0cbf 100644 --- a/modules/extensions/src/terrain/terrain-extension.ts +++ b/modules/extensions/src/terrain/terrain-extension.ts @@ -4,7 +4,7 @@ import {LayerExtension, UpdateParameters} from '@deck.gl/core'; import {TerrainEffect} from './terrain-effect'; -import {terrainModule, TerrainModuleProps} from './shader-module'; +import {terrainModule} from './shader-module'; import type {Layer} from '@deck.gl/core'; From 2ec1ffa48748c828a5ef5c02fb8b7b0d0dd129a9 Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Fri, 27 Sep 2024 18:14:37 -0700 Subject: [PATCH 2/9] Fix GPUAggregator --- .../aggregator/gpu-aggregator/webgl-bin-sorter.ts | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-bin-sorter.ts b/modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-bin-sorter.ts index cc57dc639c7..791255cf4af 100644 --- a/modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-bin-sorter.ts +++ b/modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-bin-sorter.ts @@ -105,17 +105,7 @@ export class WebGLBinSorter { model.setVertexCount(props.vertexCount); } if (props.moduleSettings) { - const {viewport, devicePixelRatio, modelMatrix, coordinateSystem, coordinateOrigin} = - props.moduleSettings; - model.shaderInputs.setProps({ - project: { - viewport, - devicePixelRatio, - modelMatrix, - coordinateSystem, - coordinateOrigin - } - }); + model.shaderInputs.setProps(props.moduleSettings); } } From 9b1af8911a7f37ca007f27232730697727cd5a42 Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Fri, 27 Sep 2024 19:57:52 -0700 Subject: [PATCH 3/9] fixes --- .../src/contour-layer/contour-layer.ts | 4 ++-- .../aggregation-layers/src/grid-layer/grid-layer.ts | 4 ++-- .../src/hexagon-layer/hexagon-layer.ts | 4 ++-- modules/carto/src/layers/post-process-utils.ts | 5 +++-- modules/core/src/lib/layer.ts | 4 ---- modules/core/src/passes/layers-pass.ts | 5 +---- modules/core/src/shaderlib/misc/layer-uniforms.ts | 12 ++++++++++-- .../extensions/src/brushing/brushing-extension.ts | 2 +- .../src/data-filter/data-filter-extension.ts | 5 ++--- .../src/fill-style/fill-style-extension.ts | 3 +-- test/modules/core/lib/layer.spec.ts | 2 +- 11 files changed, 25 insertions(+), 25 deletions(-) diff --git a/modules/aggregation-layers/src/contour-layer/contour-layer.ts b/modules/aggregation-layers/src/contour-layer/contour-layer.ts index e6a0de31d57..96361b2e433 100644 --- a/modules/aggregation-layers/src/contour-layer/contour-layer.ts +++ b/modules/aggregation-layers/src/contour-layer/contour-layer.ts @@ -286,8 +286,8 @@ export default class GridLayer extends override draw(opts) { // Replaces render time viewport with our own - if (opts.moduleParameters.viewport) { - opts.moduleParameters.viewport = this.state.aggregatorViewport; + if (opts.moduleParameters.project) { + opts.moduleParameters.project.viewport = this.state.aggregatorViewport; } super.draw(opts); } diff --git a/modules/aggregation-layers/src/grid-layer/grid-layer.ts b/modules/aggregation-layers/src/grid-layer/grid-layer.ts index 9bd822021c2..63ab5c7735e 100644 --- a/modules/aggregation-layers/src/grid-layer/grid-layer.ts +++ b/modules/aggregation-layers/src/grid-layer/grid-layer.ts @@ -489,8 +489,8 @@ export default class GridLayer extends override draw(opts) { // Replaces render time viewport with our own - if (opts.moduleParameters.viewport) { - opts.moduleParameters.viewport = this.state.aggregatorViewport; + if (opts.moduleParameters.project) { + opts.moduleParameters.project.viewport = this.state.aggregatorViewport; } super.draw(opts); } diff --git a/modules/aggregation-layers/src/hexagon-layer/hexagon-layer.ts b/modules/aggregation-layers/src/hexagon-layer/hexagon-layer.ts index 19cc95bace2..8ecee0dbdc0 100644 --- a/modules/aggregation-layers/src/hexagon-layer/hexagon-layer.ts +++ b/modules/aggregation-layers/src/hexagon-layer/hexagon-layer.ts @@ -488,8 +488,8 @@ export default class HexagonLayer< override draw(opts) { // Replaces render time viewport with our own - if (opts.moduleParameters.viewport) { - opts.moduleParameters.viewport = this.state.aggregatorViewport; + if (opts.moduleParameters.project) { + opts.moduleParameters.project.viewport = this.state.aggregatorViewport; } super.draw(opts); } diff --git a/modules/carto/src/layers/post-process-utils.ts b/modules/carto/src/layers/post-process-utils.ts index 173b16cb0c0..819bf39a78d 100644 --- a/modules/carto/src/layers/post-process-utils.ts +++ b/modules/carto/src/layers/post-process-utils.ts @@ -136,8 +136,9 @@ export function PostProcessModifier fbo.resize({width, height})); } diff --git a/modules/core/src/lib/layer.ts b/modules/core/src/lib/layer.ts index 266dadfa9e9..faddd4be6a6 100644 --- a/modules/core/src/lib/layer.ts +++ b/modules/core/src/lib/layer.ts @@ -1053,10 +1053,6 @@ export default abstract class Layer extends Component< // @ts-ignore (TS2339) internalState is alwasy defined when this method is called this.props = this.internalState.propsInTransition || currentProps; - // apply gamma to opacity to make it visually "linear" - const opacity = Math.pow(this.props.opacity, 1 / 2.2); - uniforms.opacity = opacity; // TODO remove once layers ported to UBO - try { // TODO/ib - hack move to luma Model.draw if (moduleParameters) { diff --git a/modules/core/src/passes/layers-pass.ts b/modules/core/src/passes/layers-pass.ts index b523963d255..635995e3c59 100644 --- a/modules/core/src/passes/layers-pass.ts +++ b/modules/core/src/passes/layers-pass.ts @@ -11,7 +11,6 @@ import type View from '../views/view'; import type Layer from '../lib/layer'; import type {Effect} from '../lib/effect'; import type {ProjectProps} from '../shaderlib/project/viewport-uniforms'; -import type {LayerProps} from '../shaderlib/misc/layer-uniforms'; import type {PickingProps} from '@luma.gl/shadertools'; export type Rect = {x: number; y: number; width: number; height: number}; @@ -360,9 +359,7 @@ export default class LayersPass extends Pass { const layerProps = layer.internalState?.propsInTransition || layer.props; const moduleParameters = { - layer: { - opacity: layerProps.opacity - } satisfies LayerProps, + layer: layerProps, picking: { isActive: false } satisfies PickingProps, diff --git a/modules/core/src/shaderlib/misc/layer-uniforms.ts b/modules/core/src/shaderlib/misc/layer-uniforms.ts index 0723bb42305..b6a2080d4f8 100644 --- a/modules/core/src/shaderlib/misc/layer-uniforms.ts +++ b/modules/core/src/shaderlib/misc/layer-uniforms.ts @@ -3,6 +3,7 @@ // Copyright (c) vis.gl contributors import type {ShaderModule} from '@luma.gl/shadertools'; +import type {LayerProps} from '../../types/layer-props'; const uniformBlock = `\ uniform layerUniforms { @@ -10,7 +11,7 @@ uniform layerUniforms { } layer; `; -export type LayerProps = { +export type LayerUniforms = { opacity?: number; }; @@ -18,7 +19,14 @@ export const layerUniforms = { name: 'layer', vs: uniformBlock, fs: uniformBlock, + getUniforms: (props: Partial) => { + 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' } -} as const satisfies ShaderModule; +} as const satisfies ShaderModule; diff --git a/modules/extensions/src/brushing/brushing-extension.ts b/modules/extensions/src/brushing/brushing-extension.ts index 7d7a5c25033..98b783637d9 100644 --- a/modules/extensions/src/brushing/brushing-extension.ts +++ b/modules/extensions/src/brushing/brushing-extension.ts @@ -88,7 +88,7 @@ export default class BrushingExtension extends LayerExtension { draw(this: Layer, params: any, extension: this) { const {viewport, mousePosition} = params.context; - const {brushingEnabled, brushingRadius, brushingTarget} = params.moduleParameters; + const {brushingEnabled, brushingRadius, brushingTarget} = this.props; const brushingProps: BrushingModuleProps = { viewport, mousePosition, diff --git a/modules/extensions/src/data-filter/data-filter-extension.ts b/modules/extensions/src/data-filter/data-filter-extension.ts index 27921ce26bc..f7a93676c91 100644 --- a/modules/extensions/src/data-filter/data-filter-extension.ts +++ b/modules/extensions/src/data-filter/data-filter-extension.ts @@ -266,13 +266,12 @@ export default class DataFilterExtension extends LayerExtension< const filterModel = this.state.filterModel as Model; const filterNeedsUpdate = this.state.filterNeedsUpdate as boolean; - const {onFilteredItemsChange} = this.props; - if (!this.state.categoryBitMask) { extension._updateCategoryBitMask.call(this, params, extension); } const { + onFilteredItemsChange, extensions, filterEnabled, filterRange, @@ -280,7 +279,7 @@ export default class DataFilterExtension extends LayerExtension< filterTransformSize, filterTransformColor, filterCategories - } = params.moduleParameters; + } = this.props; const dataFilterProps: DataFilterModuleProps = { extensions, filterEnabled, diff --git a/modules/extensions/src/fill-style/fill-style-extension.ts b/modules/extensions/src/fill-style/fill-style-extension.ts index 2207e492ca0..0d5ce10f6c8 100644 --- a/modules/extensions/src/fill-style/fill-style-extension.ts +++ b/modules/extensions/src/fill-style/fill-style-extension.ts @@ -159,9 +159,8 @@ export default class FillStyleExtension extends LayerExtension { onAfterUpdate: () => t.deepEquals( drawCalls.pop(), - {opacity: Math.pow(0.5, 1 / 2.2), modelMatrix: scale2Mat4}, + {opacity: 0.5, modelMatrix: scale2Mat4}, 'layer drawn with opacity in transition' ) }, From 94acd83f5b5bf3a1766209e594c0f99ac46f5ddd Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Fri, 27 Sep 2024 21:54:25 -0700 Subject: [PATCH 4/9] tests --- modules/core/src/passes/layers-pass.ts | 2 +- modules/core/src/passes/shadow-pass.ts | 2 +- test/modules/core/effects/lighting-effect.spec.ts | 12 ++++++------ test/modules/core/passes/layers-pass.spec.ts | 8 ++++++-- test/modules/core/passes/shadow-pass.spec.ts | 2 +- .../collision-filter/collision-filter-effect.spec.ts | 12 ++++++------ .../collision-filter/collision-filter-pass.spec.ts | 4 ++-- test/modules/extensions/mask/mask-effect.spec.ts | 12 ++++++------ 8 files changed, 29 insertions(+), 25 deletions(-) diff --git a/modules/core/src/passes/layers-pass.ts b/modules/core/src/passes/layers-pass.ts index 635995e3c59..ba6b4c05f26 100644 --- a/modules/core/src/passes/layers-pass.ts +++ b/modules/core/src/passes/layers-pass.ts @@ -369,7 +369,7 @@ export default class LayersPass extends Pass { modelMatrix: layerProps.modelMatrix, coordinateSystem: layerProps.coordinateSystem, coordinateOrigin: layerProps.coordinateOrigin, - autoWrapLongitude: layerProps.wrapLongitude + autoWrapLongitude: layer.wrapLongitude } satisfies ProjectProps }; diff --git a/modules/core/src/passes/shadow-pass.ts b/modules/core/src/passes/shadow-pass.ts index d7857bbb101..20ca3a7d4fb 100644 --- a/modules/core/src/passes/shadow-pass.ts +++ b/modules/core/src/passes/shadow-pass.ts @@ -88,7 +88,7 @@ export default class ShadowPass extends LayersPass { getModuleParameters(layer: Layer) { return { shadow: { - viewport: layer.context.viewport, + viewport: null, // will be populated by LayersPass at render time drawToShadowMap: true } }; diff --git a/test/modules/core/effects/lighting-effect.spec.ts b/test/modules/core/effects/lighting-effect.spec.ts index 1dc9c0db671..bd689404293 100644 --- a/test/modules/core/effects/lighting-effect.spec.ts +++ b/test/modules/core/effects/lighting-effect.spec.ts @@ -62,16 +62,16 @@ test('LightingEffect#getModuleParameters', t => { pixelRatio: 1 }); - const {lightSources} = lightingEffect.getModuleParameters(layer); - t.is(lightSources.pointLights.length, 2, 'Lights are exported'); + const {lighting} = lightingEffect.getModuleParameters(layer); + t.is(lighting.pointLights.length, 2, 'Lights are exported'); t.ok( - equals(lightSources.pointLights[0].position, [0, 0, 0.018310546875]), + equals(lighting.pointLights[0].position, [0, 0, 0.018310546875]), 'Camera light projection is ok' ); - t.deepEqual(lightSources.pointLights[1].color, [255, 0, 0], 'point light color is ok'); + t.deepEqual(lighting.pointLights[1].color, [255, 0, 0], 'point light color is ok'); - t.equal(lightSources.ambientLight, undefined, 'Lighting effect getGLParameters is ok'); - t.deepEqual(lightSources.directionalLights, [], 'Lighting effect getGLParameters is ok'); + t.equal(lighting.ambientLight, undefined, 'Lighting effect getGLParameters is ok'); + t.deepEqual(lighting.directionalLights, [], 'Lighting effect getGLParameters is ok'); lightingEffect.cleanup(effectContext); layerManager.finalize(); diff --git a/test/modules/core/passes/layers-pass.spec.ts b/test/modules/core/passes/layers-pass.spec.ts index ce6c19e175b..171f91ad6cd 100644 --- a/test/modules/core/passes/layers-pass.spec.ts +++ b/test/modules/core/passes/layers-pass.spec.ts @@ -308,7 +308,9 @@ test('LayersPass#GLViewport', t => { target: framebuffer, viewport: {}, moduleParameters: { - devicePixelRatio: 2 + project: { + devicePixelRatio: 2 + } }, expectedGLViewport: [0, 98, 2, 2] }, @@ -329,7 +331,9 @@ test('LayersPass#GLViewport', t => { target: framebuffer, viewport: {x: 5, y: 10, width: 30, height: 30}, moduleParameters: { - devicePixelRatio: 2 + project: { + devicePixelRatio: 2 + } }, expectedGLViewport: [10, 20, 60, 60] } diff --git a/test/modules/core/passes/shadow-pass.spec.ts b/test/modules/core/passes/shadow-pass.spec.ts index e648e23c588..0bd5444fcab 100644 --- a/test/modules/core/passes/shadow-pass.spec.ts +++ b/test/modules/core/passes/shadow-pass.spec.ts @@ -66,7 +66,7 @@ test('ShadowPass#getModuleParameters', t => { const shadowPass = new ShadowPass(device, {pixelRatio: 1.0}); const moduleParameters = shadowPass.getModuleParameters(layer); - t.equal(moduleParameters.drawToShadowMap, true, `ShadowPass has module parameters`); + t.equal(moduleParameters.shadow.drawToShadowMap, true, `ShadowPass has module parameters`); shadowPass.delete(); t.end(); }); diff --git a/test/modules/extensions/collision-filter/collision-filter-effect.spec.ts b/test/modules/extensions/collision-filter/collision-filter-effect.spec.ts index 3635178d6d6..e1cd9c70312 100644 --- a/test/modules/extensions/collision-filter/collision-filter-effect.spec.ts +++ b/test/modules/extensions/collision-filter/collision-filter-effect.spec.ts @@ -117,20 +117,20 @@ test('CollisionFilterEffect#update', t => { }; preRenderWithLayers([TEST_LAYER], 'Initial render'); - let parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER); + let parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER).collision; t.ok(parameters.collisionFBO, 'collision map is in parameters'); t.ok(parameters.dummyCollisionMap, 'dummy collision map is in parameters'); preRenderWithLayers([TEST_LAYER, TEST_LAYER_2], 'Add second collision layer'); - parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER); + parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER).collision; t.ok(parameters.collisionFBO, 'collision map is in parameters'); t.ok(parameters.dummyCollisionMap, 'dummy collision map is in parameters'); - parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER_2); + parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER_2).collision; t.ok(parameters.collisionFBO, 'collision map is in parameters'); t.ok(parameters.dummyCollisionMap, 'dummy collision map is in parameters'); preRenderWithLayers([TEST_LAYER_2], 'Remove first layer'); - parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER_2); + parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER_2).collision; t.ok(parameters.collisionFBO, 'collision map is in parameters'); t.ok(parameters.dummyCollisionMap, 'dummy collision map is in parameters'); @@ -138,10 +138,10 @@ test('CollisionFilterEffect#update', t => { [TEST_LAYER_2, TEST_LAYER_DIFFERENT_GROUP], 'Add layer with different collision group' ); - parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER_2); + parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER_2).collision; t.ok(parameters.collisionFBO, 'collision map is in parameters'); t.ok(parameters.dummyCollisionMap, 'dummy collision map is in parameters'); - parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER_DIFFERENT_GROUP); + parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER_DIFFERENT_GROUP).collision; t.ok(parameters.collisionFBO, 'collision map is in parameters'); t.ok(parameters.dummyCollisionMap, 'dummy collision map is in parameters'); diff --git a/test/modules/extensions/collision-filter/collision-filter-pass.spec.ts b/test/modules/extensions/collision-filter/collision-filter-pass.spec.ts index 5eb25354b36..1ddae91767b 100644 --- a/test/modules/extensions/collision-filter/collision-filter-pass.spec.ts +++ b/test/modules/extensions/collision-filter/collision-filter-pass.spec.ts @@ -12,7 +12,7 @@ test('CollisionFilterPass#getModuleParameters', t => { const moduleParameters = collisionFilterPass.getModuleParameters(); t.equal( - moduleParameters.drawToCollisionMap, + moduleParameters.collision.drawToCollisionMap, true, `CollisionFilterPass has drawToCollisionMap module parameter` ); @@ -27,7 +27,7 @@ test('CollisionFilterPass#getModuleParameters', t => { `CollisionFilterPass has picking.isAttribute module parameter` ); t.deepEqual( - moduleParameters.lightSources, + moduleParameters.lighting, {enabled: false}, `CollisionFilterPass disables lighting module` ); diff --git a/test/modules/extensions/mask/mask-effect.spec.ts b/test/modules/extensions/mask/mask-effect.spec.ts index 0a2ee55673b..317000f2694 100644 --- a/test/modules/extensions/mask/mask-effect.spec.ts +++ b/test/modules/extensions/mask/mask-effect.spec.ts @@ -95,7 +95,7 @@ test('MaskEffect#update', t => { preRenderWithLayers([TEST_MASK_LAYER, TEST_LAYER], 'Initial render'); - let parameters = maskEffect.getModuleParameters(TEST_LAYER); + let parameters = maskEffect.getModuleParameters(TEST_LAYER).mask; t.is(parameters.maskMap, maskEffect.maskMap, 'Mask map is in parameters'); let mask = parameters.maskChannels['test-mask-layer']; t.is(mask?.index, 0, 'Mask is rendered in channel 0'); @@ -104,7 +104,7 @@ test('MaskEffect#update', t => { preRenderWithLayers([TEST_MASK_LAYER, TEST_LAYER, TEST_MASK_LAYER2], 'Add second mask'); - parameters = maskEffect.getModuleParameters(TEST_LAYER); + parameters = maskEffect.getModuleParameters(TEST_LAYER).mask; mask = parameters.maskChannels['test-mask-layer']; t.is(mask?.index, 0, 'Mask is rendered in channel 0'); t.is(mask?.bounds, bounds, 'Using cached mask bounds'); @@ -115,7 +115,7 @@ test('MaskEffect#update', t => { preRenderWithLayers([TEST_LAYER, TEST_MASK_LAYER2], 'Remove first mask'); - parameters = maskEffect.getModuleParameters(TEST_LAYER); + parameters = maskEffect.getModuleParameters(TEST_LAYER).mask; mask = parameters.maskChannels['test-mask-layer']; t.notOk(mask, 'Mask is removed'); mask = parameters.maskChannels['test-mask-layer-2']; @@ -127,7 +127,7 @@ test('MaskEffect#update', t => { 'Update second mask, add third' ); - parameters = maskEffect.getModuleParameters(TEST_LAYER); + parameters = maskEffect.getModuleParameters(TEST_LAYER).mask; mask = parameters.maskChannels['test-mask-layer-2']; t.is(mask?.index, 1, 'Second mask is rendered in channel 1'); t.not(mask?.bounds, bounds, 'Second mask is updated'); @@ -165,14 +165,14 @@ test('MaskEffect#coordinates', t => { preRenderWithLayers([TEST_MASK_LAYER, TEST_LAYER], 'Initial render'); - let parameters = maskEffect.getModuleParameters(TEST_LAYER); + let parameters = maskEffect.getModuleParameters(TEST_LAYER).mask; let mask = parameters.maskChannels['test-mask-layer']; t.same(mask?.coordinateOrigin, [0, 0, 0], 'Mask has correct coordinate origin'); t.is(mask?.coordinateSystem, COORDINATE_SYSTEM.DEFAULT, 'Mask has correct coordinate system'); preRenderWithLayers([TEST_MASK_LAYER_CARTESIAN, TEST_LAYER], 'Update to cartesion coordinates'); - parameters = maskEffect.getModuleParameters(TEST_LAYER); + parameters = maskEffect.getModuleParameters(TEST_LAYER).mask; mask = parameters.maskChannels['test-mask-layer']; t.same(mask?.coordinateOrigin, [1, 2, 3], 'Mask has correct coordinate origin'); t.is(mask?.coordinateSystem, COORDINATE_SYSTEM.CARTESIAN, 'Mask has correct coordinate system'); From 5e1c0956eb8a2a9ebe128a0522666231b3bbf3ca Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Sun, 29 Sep 2024 10:02:03 -0700 Subject: [PATCH 5/9] address comments --- .../src/common/aggregation-layer.ts | 4 +- .../src/contour-layer/contour-layer.ts | 4 +- .../src/grid-layer/grid-layer.ts | 4 +- .../src/heatmap-layer/aggregation-layer.ts | 2 +- .../src/hexagon-layer/hexagon-layer.ts | 4 +- .../carto/src/layers/post-process-utils.ts | 8 +-- .../src/effects/lighting/lighting-effect.ts | 25 ++++----- modules/core/src/index.ts | 2 +- modules/core/src/lib/effect.ts | 2 +- modules/core/src/lib/layer.ts | 22 +++----- modules/core/src/passes/layers-pass.ts | 54 ++++++++++--------- modules/core/src/passes/pick-layers-pass.ts | 6 +-- modules/core/src/passes/shadow-pass.ts | 4 +- modules/core/src/shaderlib/index.ts | 2 +- modules/core/src/shaderlib/shadow/shadow.ts | 18 +++---- .../collision-filter-effect.ts | 4 +- .../collision-filter-extension.ts | 4 +- .../collision-filter/collision-filter-pass.ts | 2 +- .../src/fill-style/fill-style-extension.ts | 3 +- .../src/fill-style/shader-module.ts | 8 +-- modules/extensions/src/mask/mask-effect.ts | 4 +- modules/extensions/src/mask/mask-extension.ts | 4 +- .../extensions/src/terrain/shader-module.ts | 6 +-- .../extensions/src/terrain/terrain-effect.ts | 12 +++-- .../layers/src/bitmap-layer/bitmap-layer.ts | 4 +- .../core/effects/lighting-effect.spec.ts | 4 +- test/modules/core/passes/layers-pass.spec.ts | 8 +-- test/modules/core/passes/shadow-pass.spec.ts | 6 +-- .../collision-filter-effect.spec.ts | 12 ++--- .../collision-filter-pass.spec.ts | 12 ++--- .../extensions/mask/mask-effect.spec.ts | 12 ++--- 31 files changed, 128 insertions(+), 138 deletions(-) diff --git a/modules/aggregation-layers/src/common/aggregation-layer.ts b/modules/aggregation-layers/src/common/aggregation-layer.ts index e64f1c0b325..65b96409b1f 100644 --- a/modules/aggregation-layers/src/common/aggregation-layer.ts +++ b/modules/aggregation-layers/src/common/aggregation-layer.ts @@ -86,12 +86,12 @@ export default abstract class AggregationLayer< aggregator.update(); } - draw({moduleParameters}) { + draw({shaderModuleProps}) { // GPU aggregation needs `moduleSettings` for projection/filter uniforms which are only accessible at draw time // GPUAggregator's Buffers are pre-allocated during `update()` and passed down to the sublayer attributes in renderLayers() // Although the Buffers have been bound to the sublayer's Model, their content are not populated yet // GPUAggregator.preDraw() is called in the draw cycle here right before Buffers are used by sublayer.draw() - this.state.aggregator.preDraw({moduleSettings: moduleParameters}); + this.state.aggregator.preDraw({moduleSettings: shaderModuleProps}); } // override CompositeLayer._getAttributeManager to create AttributeManager instance diff --git a/modules/aggregation-layers/src/contour-layer/contour-layer.ts b/modules/aggregation-layers/src/contour-layer/contour-layer.ts index 96361b2e433..ded0d2acd82 100644 --- a/modules/aggregation-layers/src/contour-layer/contour-layer.ts +++ b/modules/aggregation-layers/src/contour-layer/contour-layer.ts @@ -286,8 +286,8 @@ export default class GridLayer extends override draw(opts) { // Replaces render time viewport with our own - if (opts.moduleParameters.project) { - opts.moduleParameters.project.viewport = this.state.aggregatorViewport; + if (opts.shaderModuleProps.project) { + opts.shaderModuleProps.project.viewport = this.state.aggregatorViewport; } super.draw(opts); } diff --git a/modules/aggregation-layers/src/grid-layer/grid-layer.ts b/modules/aggregation-layers/src/grid-layer/grid-layer.ts index 63ab5c7735e..eb748d365f4 100644 --- a/modules/aggregation-layers/src/grid-layer/grid-layer.ts +++ b/modules/aggregation-layers/src/grid-layer/grid-layer.ts @@ -489,8 +489,8 @@ export default class GridLayer extends override draw(opts) { // Replaces render time viewport with our own - if (opts.moduleParameters.project) { - opts.moduleParameters.project.viewport = this.state.aggregatorViewport; + if (opts.shaderModuleProps.project) { + opts.shaderModuleProps.project.viewport = this.state.aggregatorViewport; } super.draw(opts); } diff --git a/modules/aggregation-layers/src/heatmap-layer/aggregation-layer.ts b/modules/aggregation-layers/src/heatmap-layer/aggregation-layer.ts index f5bbb878b1e..fbfe2b259ab 100644 --- a/modules/aggregation-layers/src/heatmap-layer/aggregation-layer.ts +++ b/modules/aggregation-layers/src/heatmap-layer/aggregation-layer.ts @@ -68,7 +68,7 @@ export default abstract class AggregationLayer< getModuleSettings() { // For regular layer draw this happens during draw cycle (_drawLayersInViewport) not during update cycle // For aggregation layers this is called during updateState to update aggregation data - // NOTE: it is similar to LayerPass._getModuleParameters() but doesn't inlcude `effects` it is not needed for aggregation + // NOTE: it is similar to LayerPass._getShaderModuleProps() but doesn't inlcude `effects` it is not needed for aggregation const {viewport, mousePosition, device} = this.context; const moduleSettings = Object.assign(Object.create(this.props), { viewport, diff --git a/modules/aggregation-layers/src/hexagon-layer/hexagon-layer.ts b/modules/aggregation-layers/src/hexagon-layer/hexagon-layer.ts index 8ecee0dbdc0..27712f7cb2b 100644 --- a/modules/aggregation-layers/src/hexagon-layer/hexagon-layer.ts +++ b/modules/aggregation-layers/src/hexagon-layer/hexagon-layer.ts @@ -488,8 +488,8 @@ export default class HexagonLayer< override draw(opts) { // Replaces render time viewport with our own - if (opts.moduleParameters.project) { - opts.moduleParameters.project.viewport = this.state.aggregatorViewport; + if (opts.shaderModuleProps.project) { + opts.shaderModuleProps.project.viewport = this.state.aggregatorViewport; } super.draw(opts); } diff --git a/modules/carto/src/layers/post-process-utils.ts b/modules/carto/src/layers/post-process-utils.ts index 819bf39a78d..dd09f728566 100644 --- a/modules/carto/src/layers/post-process-utils.ts +++ b/modules/carto/src/layers/post-process-utils.ts @@ -68,8 +68,8 @@ export function RTTModifier(BaseLayer) { static layerName = `RTT-${BaseLayer.layerName}`; draw(this: RTTLayer, opts: any) { - const {moduleParameters} = opts; - const {picking} = moduleParameters; + const {shaderModuleProps} = opts; + const {picking} = shaderModuleProps; const postProcessLayer = getPostProcessLayer(this); if (!picking.isActive) { @@ -134,9 +134,9 @@ export function PostProcessModifier fbo.resize({width, height})); diff --git a/modules/core/src/effects/lighting/lighting-effect.ts b/modules/core/src/effects/lighting/lighting-effect.ts index 0cc6470f8f0..581fe09e288 100644 --- a/modules/core/src/effects/lighting/lighting-effect.ts +++ b/modules/core/src/effects/lighting/lighting-effect.ts @@ -11,9 +11,10 @@ import {Matrix4, Vector3} from '@math.gl/core'; import ShadowPass from '../../passes/shadow-pass'; import shadow from '../../shaderlib/shadow/shadow'; +import type {LightingProps} from '@luma.gl/shadertools'; +import type {ShadowModuleProps} from '../../shaderlib/shadow/shadow'; import type Layer from '../../lib/layer'; import type {Effect, EffectContext, PreRenderOptions} from '../../lib/effect'; -import type Viewport from '../../viewports/viewport'; const DEFAULT_AMBIENT_LIGHT_PROPS = { color: [255, 255, 255] as [number, number, number], @@ -117,7 +118,7 @@ export default class LightingEffect implements Effect { viewports, onViewportActive, views, - moduleParameters: { + shaderModuleProps: { shadow: { shadowLightId: i, dummyShadowMap: this.dummyShadowMap, @@ -128,26 +129,20 @@ export default class LightingEffect implements Effect { } } - getModuleParameters(layer: Layer) { - const shadowProps: { - viewport?: Viewport; - shadowMaps?: Texture[]; - dummyShadowMap?: Texture | null; - shadowColor?: [number, number, number, number]; - shadowMatrices?: Matrix4[]; - } = this.shadow - ? { - viewport: layer.context.viewport, + getShaderModuleProps(layer: Layer, otherShaderModuleProps: Record) { + const shadowProps = this.shadow + ? ({ + project: otherShaderModuleProps.project, shadowMaps: this.shadowPasses.map(shadowPass => shadowPass.getShadowMap()), - dummyShadowMap: this.dummyShadowMap, + dummyShadowMap: this.dummyShadowMap!, shadowColor: this.shadowColor, shadowMatrices: this.shadowMatrices - } + } satisfies ShadowModuleProps) : {}; // when not rendering to screen, turn off lighting by adding empty light source object // lights shader module relies on the `lightSources` to turn on/off lighting - const lightingProps = { + const lightingProps: LightingProps = { enabled: true, ambientLight: this.ambientLight, directionalLights: this.directionalLights.map(directionalLight => diff --git a/modules/core/src/index.ts b/modules/core/src/index.ts index 72bdcb1a935..b76c565f2dd 100644 --- a/modules/core/src/index.ts +++ b/modules/core/src/index.ts @@ -125,7 +125,7 @@ export type {PickingInfo, GetPickingInfoParams} from './lib/picking/pick-info'; export type {ConstructorOf as _ConstructorOf} from './types/types'; export type {BinaryAttribute} from './lib/attribute/attribute'; export type {Effect, EffectContext, PreRenderOptions, PostRenderOptions} from './lib/effect'; -export type {PickingUniforms, ProjectUniforms} from './shaderlib/index'; +export type {PickingUniforms, ProjectProps, ProjectUniforms} from './shaderlib/index'; export type {DefaultProps} from './lifecycle/prop-types'; export type {LayersPassRenderOptions} from './passes/layers-pass'; export type {Widget, WidgetPlacement} from './lib/widget-manager'; diff --git a/modules/core/src/lib/effect.ts b/modules/core/src/lib/effect.ts index 89c0df9bbaa..c6e7164bba6 100644 --- a/modules/core/src/lib/effect.ts +++ b/modules/core/src/lib/effect.ts @@ -32,7 +32,7 @@ export interface Effect { /** Called after layers are rendered to screen */ postRender?(opts: PostRenderOptions): Framebuffer | null; /** Module settings passed to models */ - getModuleParameters?(layer: Layer): any; + getShaderModuleProps?(layer: Layer, otherShaderModuleProps: Record): any; // / Lifecycle methods /** Called when this effect is added */ diff --git a/modules/core/src/lib/layer.ts b/modules/core/src/lib/layer.ts index faddd4be6a6..420caa5bbaf 100644 --- a/modules/core/src/lib/layer.ts +++ b/modules/core/src/lib/layer.ts @@ -321,15 +321,6 @@ export default abstract class Layer extends Component< return (state && (state.models || (state.model && [state.model]))) || []; } - // TODO deprecate in favour of setShaderModuleProps - /** Update shader module parameters */ - setModuleParameters(moduleParameters: any): void { - for (const model of this.getModels()) { - // HACK as fp64 is not yet ported to UBO - model.uniforms = {ONE: 1}; - } - } - /** Update shader input parameters */ setShaderModuleProps(...props: Parameters): void { for (const model of this.getModels()) { @@ -1035,12 +1026,12 @@ export default abstract class Layer extends Component< // Calculates uniforms _drawLayer({ renderPass, - moduleParameters = null, + shaderModuleProps = null, uniforms = {}, parameters = {} }: { renderPass: RenderPass; - moduleParameters: any; + shaderModuleProps: any; uniforms: any; parameters: any; }): void { @@ -1055,9 +1046,8 @@ export default abstract class Layer extends Component< try { // TODO/ib - hack move to luma Model.draw - if (moduleParameters) { - this.setModuleParameters({}); - this.setShaderModuleProps(moduleParameters); + if (shaderModuleProps) { + this.setShaderModuleProps(shaderModuleProps); } // Apply polygon offset to avoid z-fighting @@ -1076,7 +1066,7 @@ export default abstract class Layer extends Component< // Call subclass lifecycle method if (context.device instanceof WebGLDevice) { context.device.withParametersWebGL(parameters, () => { - const opts = {renderPass, moduleParameters, uniforms, parameters, context}; + const opts = {renderPass, shaderModuleProps, uniforms, parameters, context}; // extensions for (const extension of this.props.extensions) { @@ -1086,7 +1076,7 @@ export default abstract class Layer extends Component< this.draw(opts); }); } else { - const opts = {renderPass, moduleParameters, uniforms, parameters, context}; + const opts = {renderPass, shaderModuleProps, uniforms, parameters, context}; // extensions for (const extension of this.props.extensions) { diff --git a/modules/core/src/passes/layers-pass.ts b/modules/core/src/passes/layers-pass.ts index ba6b4c05f26..816a1705337 100644 --- a/modules/core/src/passes/layers-pass.ts +++ b/modules/core/src/passes/layers-pass.ts @@ -33,7 +33,7 @@ export type LayersPassRenderOptions = { colorMask?: number; scissorRect?: number[]; layerFilter?: ((context: FilterContext) => boolean) | null; - moduleParameters?: any; + shaderModuleProps?: any; /** Stores returned results from Effect.preRender, for use downstream in the render pipeline */ preRenderStats?: Record; }; @@ -41,7 +41,7 @@ export type LayersPassRenderOptions = { type DrawLayerParameters = { shouldDrawLayer: boolean; layerRenderIndex?: number; - moduleParameters?: any; + shaderModuleProps?: any; layerParameters?: any; }; @@ -102,7 +102,7 @@ export default class LayersPass extends Pass { private _drawLayers(renderPass: RenderPass, options: LayersPassRenderOptions) { const { target, - moduleParameters, + shaderModuleProps, viewports, views, onViewportActive, @@ -131,7 +131,7 @@ export default class LayersPass extends Pass { renderPass, { target, - moduleParameters, + shaderModuleProps, viewport: subViewport, view, pass: options.pass, @@ -157,7 +157,7 @@ export default class LayersPass extends Pass { layerFilter, cullRect, effects, - moduleParameters + shaderModuleProps }: LayersPassRenderOptions, /** Internal flag, true if only used to determine whether each layer should be drawn */ evaluateShouldDrawOnly: boolean = false @@ -192,11 +192,11 @@ export default class LayersPass extends Pass { // It can be the same as another layer layerParam.layerRenderIndex = indexResolver(layer, shouldDrawLayer); - layerParam.moduleParameters = this._getModuleParameters( + layerParam.shaderModuleProps = this._getShaderModuleProps( layer, effects, pass, - moduleParameters + shaderModuleProps ); layerParam.layerParameters = { ...layer.context.deck?.props.parameters, @@ -214,11 +214,11 @@ export default class LayersPass extends Pass { /* eslint-disable max-depth, max-statements */ private _drawLayersInViewport( renderPass: RenderPass, - {layers, moduleParameters: globalModuleParameters, pass, target, viewport, view}, + {layers, shaderModuleProps: globalModuleParameters, pass, target, viewport, view}, drawLayerParams ): RenderStats { const glViewport = getGLViewport(this.device, { - moduleParameters: globalModuleParameters, + shaderModuleProps: globalModuleParameters, target, viewport }); @@ -248,7 +248,7 @@ export default class LayersPass extends Pass { // render layers in normal colors for (let layerIndex = 0; layerIndex < layers.length; layerIndex++) { const layer = layers[layerIndex] as Layer; - const {shouldDrawLayer, layerRenderIndex, moduleParameters, layerParameters} = + const {shouldDrawLayer, layerRenderIndex, shaderModuleProps, layerParameters} = drawLayerParams[layerIndex]; // Calculate stats @@ -265,11 +265,8 @@ export default class LayersPass extends Pass { this._lastRenderIndex = Math.max(this._lastRenderIndex, layerRenderIndex); // overwrite layer.context.viewport with the sub viewport - for (const moduleName in moduleParameters) { - const moduleProps = moduleParameters[moduleName]; - if (moduleProps && typeof moduleProps === 'object' && 'viewport' in moduleProps) { - moduleProps.viewport = viewport; - } + if (shaderModuleProps.project) { + shaderModuleProps.project.viewport = viewport; } // TODO v9 - we are sending renderPass both as a parameter and through the context. @@ -280,7 +277,7 @@ export default class LayersPass extends Pass { try { layer._drawLayer({ renderPass, - moduleParameters, + shaderModuleProps, uniforms: {layerIndex: layerRenderIndex}, parameters: layerParameters }); @@ -299,7 +296,11 @@ export default class LayersPass extends Pass { return true; } - protected getModuleParameters(layer: Layer, effects?: Effect[]): any { + protected getShaderModuleProps( + layer: Layer, + effects: Effect[] | undefined, + otherShaderModuleProps: Record + ): any { return null; } @@ -348,7 +349,7 @@ export default class LayersPass extends Pass { return true; } - private _getModuleParameters( + private _getShaderModuleProps( layer: Layer, effects: Effect[] | undefined, pass: string, @@ -358,7 +359,7 @@ export default class LayersPass extends Pass { const devicePixelRatio = this.device.canvasContext.cssToDeviceRatio(); const layerProps = layer.internalState?.propsInTransition || layer.props; - const moduleParameters = { + const shaderModuleProps = { layer: layerProps, picking: { isActive: false @@ -375,13 +376,16 @@ export default class LayersPass extends Pass { if (effects) { for (const effect of effects) { - mergeModuleParameters(moduleParameters, effect.getModuleParameters?.(layer)); + mergeModuleParameters( + shaderModuleProps, + effect.getShaderModuleProps?.(layer, shaderModuleProps) + ); } } return mergeModuleParameters( - moduleParameters, - this.getModuleParameters(layer, effects), + shaderModuleProps, + this.getShaderModuleProps(layer, effects, shaderModuleProps), overrides ); } @@ -439,17 +443,17 @@ export function layerIndexResolver( function getGLViewport( device: Device, { - moduleParameters, + shaderModuleProps, target, viewport }: { - moduleParameters: any; + shaderModuleProps: any; target?: Framebuffer; viewport: Viewport; } ): [number, number, number, number] { const pixelRatio = - moduleParameters?.project?.devicePixelRatio ?? + shaderModuleProps?.project?.devicePixelRatio ?? // @ts-expect-error TODO - assuming WebGL context device.canvasContext.cssToDeviceRatio(); diff --git a/modules/core/src/passes/pick-layers-pass.ts b/modules/core/src/passes/pick-layers-pass.ts index a5bded2c1a9..8edbaf2a88f 100644 --- a/modules/core/src/passes/pick-layers-pass.ts +++ b/modules/core/src/passes/pick-layers-pass.ts @@ -69,7 +69,7 @@ export default class PickLayersPass extends LayersPass { effects, pass = 'picking', pickZ, - moduleParameters + shaderModuleProps }: PickLayersPassRenderOptions): { decodePickingColor: PickingColorDecoder | null; stats: RenderStats; @@ -94,7 +94,7 @@ export default class PickLayersPass extends LayersPass { effects: effects?.filter(e => e.useInPicking), pass, isPicking: true, - moduleParameters, + shaderModuleProps, clearColor: [0, 0, 0, 0], colorMask: 0xf, scissorRect @@ -115,7 +115,7 @@ export default class PickLayersPass extends LayersPass { ); } - protected getModuleParameters() { + protected getShaderModuleProps() { return { picking: { isActive: 1, diff --git a/modules/core/src/passes/shadow-pass.ts b/modules/core/src/passes/shadow-pass.ts index 20ca3a7d4fb..d560b859231 100644 --- a/modules/core/src/passes/shadow-pass.ts +++ b/modules/core/src/passes/shadow-pass.ts @@ -85,10 +85,10 @@ export default class ShadowPass extends LayersPass { return layer.props.shadowEnabled !== false; } - getModuleParameters(layer: Layer) { + getShaderModuleProps(layer: Layer, effects: any, otherShaderModuleProps: Record) { return { shadow: { - viewport: null, // will be populated by LayersPass at render time + project: otherShaderModuleProps.project, drawToShadowMap: true } }; diff --git a/modules/core/src/shaderlib/index.ts b/modules/core/src/shaderlib/index.ts index d1e3279cc80..85c7d67a2fc 100644 --- a/modules/core/src/shaderlib/index.ts +++ b/modules/core/src/shaderlib/index.ts @@ -37,7 +37,7 @@ export function getShaderAssembler() { export {layerUniforms, picking, project, project32, gouraudLighting, phongLighting, shadow}; // Useful for custom shader modules -export type {ProjectUniforms} from './project/viewport-uniforms'; +export type {ProjectProps, ProjectUniforms} from './project/viewport-uniforms'; // TODO - these should be imported from luma.gl /* eslint-disable camelcase */ diff --git a/modules/core/src/shaderlib/shadow/shadow.ts b/modules/core/src/shaderlib/shadow/shadow.ts index a10c1253708..50870010a11 100644 --- a/modules/core/src/shaderlib/shadow/shadow.ts +++ b/modules/core/src/shaderlib/shadow/shadow.ts @@ -12,7 +12,7 @@ import {pixelsToWorld} from '@math.gl/web-mercator'; import type {Texture} from '@luma.gl/core'; import {ShaderModule} from '@luma.gl/shadertools'; import type Viewport from '../../viewports/viewport'; -import type {ProjectUniforms} from '../project/viewport-uniforms'; +import type {ProjectProps, ProjectUniforms} from '../project/viewport-uniforms'; const uniformBlock = /* glsl */ ` uniform shadowUniforms { @@ -114,8 +114,8 @@ const getMemoizedViewProjectionMatrices = memoize(getViewProjectionMatrices); const DEFAULT_SHADOW_COLOR: NumberArray4 = [0, 0, 0, 1.0]; const VECTOR_TO_POINT_MATRIX = [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0]; -type ShadowModuleProps = { - viewport: Viewport; +export type ShadowModuleProps = { + project: ProjectProps; shadowEnabled?: boolean; drawToShadowMap?: boolean; shadowMaps?: Texture[]; @@ -208,8 +208,8 @@ function getViewProjectionMatrices({ function createShadowUniforms( opts: Partial ): ShadowModuleBindings & ShadowModuleUniforms { - const {shadowEnabled = true} = opts; - if (!shadowEnabled || !opts.shadowMatrices || !opts.shadowMatrices.length) { + const {shadowEnabled = true, project: projectProps} = opts; + if (!shadowEnabled || !projectProps || !opts.shadowMatrices || !opts.shadowMatrices.length) { return { drawShadowMap: false, useShadowMap: false, @@ -217,23 +217,23 @@ function createShadowUniforms( shadow_uShadowMap1: opts.dummyShadowMap! }; } - const projectUniforms = project.getUniforms(opts) as ProjectUniforms; + const projectUniforms = project.getUniforms(projectProps) as ProjectUniforms; const center = getMemoizedViewportCenterPosition({ - viewport: opts.viewport!, + viewport: projectProps.viewport, center: projectUniforms.center }); const projectCenters: NumericArray[] = []; const viewProjectionMatrices = getMemoizedViewProjectionMatrices({ shadowMatrices: opts.shadowMatrices, - viewport: opts.viewport! + viewport: projectProps.viewport }).slice(); for (let i = 0; i < opts.shadowMatrices.length; i++) { const viewProjectionMatrix = viewProjectionMatrices[i]; const viewProjectionMatrixCentered = viewProjectionMatrix .clone() - .translate(new Vector3(opts.viewport!.center).negate()); + .translate(new Vector3(projectProps.viewport.center).negate()); if ( projectUniforms.coordinateSystem === COORDINATE_SYSTEM.LNGLAT && diff --git a/modules/extensions/src/collision-filter/collision-filter-effect.ts b/modules/extensions/src/collision-filter/collision-filter-effect.ts index d3a79ef129d..742dc6860f6 100644 --- a/modules/extensions/src/collision-filter/collision-filter-effect.ts +++ b/modules/extensions/src/collision-filter/collision-filter-effect.ts @@ -157,7 +157,7 @@ export default class CollisionFilterEffect implements Effect { viewports: viewport ? [viewport] : [], onViewportActive, views, - moduleParameters: { + shaderModuleProps: { collision: { enabled: true, // To avoid feedback loop forming between Framebuffer and active Texture. @@ -213,7 +213,7 @@ export default class CollisionFilterEffect implements Effect { return channelMap; } - getModuleParameters(layer: Layer): { + getShaderModuleProps(layer: Layer): { collision: CollisionModuleProps; } { const {collisionGroup, collisionEnabled} = (layer as Layer) diff --git a/modules/extensions/src/collision-filter/collision-filter-extension.ts b/modules/extensions/src/collision-filter/collision-filter-extension.ts index b4e1ba31493..9c4d3c2112f 100644 --- a/modules/extensions/src/collision-filter/collision-filter-extension.ts +++ b/modules/extensions/src/collision-filter/collision-filter-extension.ts @@ -46,8 +46,8 @@ export default class CollisionFilterExtension extends LayerExtension { } /* eslint-disable camelcase */ - draw(this: Layer, {moduleParameters}: any) { - if (moduleParameters.collision?.drawToCollisionMap) { + draw(this: Layer, {shaderModuleProps}: any) { + if (shaderModuleProps.collision?.drawToCollisionMap) { // Override any props with those defined in collisionTestProps // @ts-ignore this.props = this.clone(this.props.collisionTestProps).props; diff --git a/modules/extensions/src/collision-filter/collision-filter-pass.ts b/modules/extensions/src/collision-filter/collision-filter-pass.ts index cc197eaa183..0b4dcf6f7b7 100644 --- a/modules/extensions/src/collision-filter/collision-filter-pass.ts +++ b/modules/extensions/src/collision-filter/collision-filter-pass.ts @@ -20,7 +20,7 @@ export default class CollisionFilterPass extends LayersPass { return {...layer.props.parameters, blend: false, depthRange: [0, 1], depthTest: true}; } - getModuleParameters() { + getShaderModuleProps() { // Draw picking colors into collision FBO return { collision: { diff --git a/modules/extensions/src/fill-style/fill-style-extension.ts b/modules/extensions/src/fill-style/fill-style-extension.ts index 0d5ce10f6c8..1df03e11f0b 100644 --- a/modules/extensions/src/fill-style/fill-style-extension.ts +++ b/modules/extensions/src/fill-style/fill-style-extension.ts @@ -160,9 +160,8 @@ export default class FillStyleExtension extends LayerExtension | null; diff --git a/modules/extensions/src/mask/mask-extension.ts b/modules/extensions/src/mask/mask-extension.ts index b3a08a5f2c8..ea3742e064e 100644 --- a/modules/extensions/src/mask/mask-extension.ts +++ b/modules/extensions/src/mask/mask-extension.ts @@ -53,11 +53,11 @@ export default class MaskExtension extends LayerExtension { } /* eslint-disable camelcase */ - draw(this: Layer>, {context, moduleParameters}: any) { + draw(this: Layer>, {context, shaderModuleProps}: any) { const maskProps = {} as MaskProps; maskProps.maskByInstance = Boolean(this.state.maskByInstance); const {maskId, maskInverted} = this.props; - const {maskChannels} = moduleParameters.mask || {}; + const {maskChannels} = shaderModuleProps.mask || {}; const {viewport} = context; if (maskChannels && maskChannels[maskId]) { const {index, bounds, coordinateOrigin: fromCoordinateOrigin} = maskChannels[maskId]; diff --git a/modules/extensions/src/terrain/shader-module.ts b/modules/extensions/src/terrain/shader-module.ts index bdb39a4fb2b..ed951fc1b35 100644 --- a/modules/extensions/src/terrain/shader-module.ts +++ b/modules/extensions/src/terrain/shader-module.ts @@ -5,7 +5,7 @@ /* eslint-disable camelcase */ import type {ShaderModule} from '@luma.gl/shadertools'; -import {project, ProjectUniforms, Viewport} from '@deck.gl/core'; +import {project, ProjectProps, ProjectUniforms, Viewport} from '@deck.gl/core'; import type {Texture} from '@luma.gl/core'; import type {Bounds} from '../utils/projection-utils'; @@ -13,7 +13,7 @@ import type {TerrainCover} from './terrain-cover'; /** Module parameters expected by the terrain shader module */ export type TerrainModuleProps = { - viewport: Viewport; + project: ProjectProps; isPicking: boolean; heightMap: Texture | null; heightMapBounds?: Bounds | null; @@ -129,7 +129,7 @@ if ((terrain.mode == TERRAIN_MODE_USE_COVER) || (terrain.mode == TERRAIN_MODE_US useTerrainHeightMap, terrainSkipRender } = opts; - const projectUniforms = project.getUniforms(opts) as ProjectUniforms; + const projectUniforms = project.getUniforms(opts.project) as ProjectUniforms; const {commonOrigin} = projectUniforms; let mode: number = terrainSkipRender ? TERRAIN_MODE.SKIP : TERRAIN_MODE.NONE; diff --git a/modules/extensions/src/terrain/terrain-effect.ts b/modules/extensions/src/terrain/terrain-effect.ts index 3dab88c3e59..d22bf507194 100644 --- a/modules/extensions/src/terrain/terrain-effect.ts +++ b/modules/extensions/src/terrain/terrain-effect.ts @@ -86,13 +86,15 @@ export class TerrainEffect implements Effect { this._updateTerrainCovers(terrainLayers, drapeLayers, viewport, opts); } - getModuleParameters(layer: Layer): {terrain: TerrainModuleProps} { - const {viewport} = layer.context; + getShaderModuleProps( + layer: Layer, + otherShaderModuleProps: Record + ): {terrain: TerrainModuleProps} { const {terrainDrawMode} = layer.state; return { terrain: { - viewport, + project: otherShaderModuleProps.project, isPicking: this.isPicking, heightMap: this.heightMap?.getRenderFramebuffer()?.colorAttachments[0].texture || null, heightMapBounds: this.heightMap?.bounds, @@ -137,7 +139,7 @@ export class TerrainEffect implements Effect { this.terrainPass.renderHeightMap(this.heightMap, { ...opts, layers: terrainLayers, - moduleParameters: { + shaderModuleProps: { terrain: { viewport, heightMapBounds: this.heightMap.bounds, @@ -200,7 +202,7 @@ export class TerrainEffect implements Effect { renderPass.renderTerrainCover(terrainCover, { ...opts, layers: drapeLayers, - moduleParameters: { + shaderModuleProps: { terrain: { viewport, dummyHeightMap: this.dummyHeightMap, diff --git a/modules/layers/src/bitmap-layer/bitmap-layer.ts b/modules/layers/src/bitmap-layer/bitmap-layer.ts index fd2126ad99a..cb73a39ec01 100644 --- a/modules/layers/src/bitmap-layer/bitmap-layer.ts +++ b/modules/layers/src/bitmap-layer/bitmap-layer.ts @@ -268,11 +268,11 @@ export default class BitmapLayer extends Layer< } draw(opts) { - const {moduleParameters, uniforms} = opts; + const {shaderModuleProps, uniforms} = opts; const {model, coordinateConversion, bounds, disablePicking} = this.state; const {image, desaturate, transparentColor, tintColor} = this.props; - if (moduleParameters.picking.isActive && disablePicking) { + if (shaderModuleProps.picking.isActive && disablePicking) { return; } diff --git a/test/modules/core/effects/lighting-effect.spec.ts b/test/modules/core/effects/lighting-effect.spec.ts index bd689404293..0fadc130d59 100644 --- a/test/modules/core/effects/lighting-effect.spec.ts +++ b/test/modules/core/effects/lighting-effect.spec.ts @@ -35,7 +35,7 @@ test('LightingEffect#constructor', t => { t.end(); }); -test('LightingEffect#getModuleParameters', t => { +test('LightingEffect#getShaderModuleProps', t => { const cameraLight = new CameraLight(); const pointLight = new PointLight(); const lightingEffect = new LightingEffect({cameraLight, pointLight}); @@ -62,7 +62,7 @@ test('LightingEffect#getModuleParameters', t => { pixelRatio: 1 }); - const {lighting} = lightingEffect.getModuleParameters(layer); + const {lighting} = lightingEffect.getShaderModuleProps(layer); t.is(lighting.pointLights.length, 2, 'Lights are exported'); t.ok( equals(lighting.pointLights[0].position, [0, 0, 0.018310546875]), diff --git a/test/modules/core/passes/layers-pass.spec.ts b/test/modules/core/passes/layers-pass.spec.ts index 171f91ad6cd..f1229989cfb 100644 --- a/test/modules/core/passes/layers-pass.spec.ts +++ b/test/modules/core/passes/layers-pass.spec.ts @@ -307,7 +307,7 @@ test('LayersPass#GLViewport', t => { name: 'external framebuffer pixel ratio 2', target: framebuffer, viewport: {}, - moduleParameters: { + shaderModuleProps: { project: { devicePixelRatio: 2 } @@ -330,7 +330,7 @@ test('LayersPass#GLViewport', t => { name: 'external framebuffer offset pixel ratio 2', target: framebuffer, viewport: {x: 5, y: 10, width: 30, height: 30}, - moduleParameters: { + shaderModuleProps: { project: { devicePixelRatio: 2 } @@ -339,13 +339,13 @@ test('LayersPass#GLViewport', t => { } ]; - for (const {name, target, viewport, moduleParameters, expectedGLViewport} of testCases) { + for (const {name, target, viewport, shaderModuleProps, expectedGLViewport} of testCases) { layersPass.render({ target, viewports: [new Viewport({id: 'A', ...viewport})], layers: layerManager.getLayers(), onViewportActive: layerManager.activateViewport, - moduleParameters, + shaderModuleProps, onError: t.notOk }); diff --git a/test/modules/core/passes/shadow-pass.spec.ts b/test/modules/core/passes/shadow-pass.spec.ts index 0bd5444fcab..ffe7cf112bb 100644 --- a/test/modules/core/passes/shadow-pass.spec.ts +++ b/test/modules/core/passes/shadow-pass.spec.ts @@ -56,7 +56,7 @@ test('ShadowPass#render', t => { t.end(); }); -test('ShadowPass#getModuleParameters', t => { +test('ShadowPass#getShaderModuleProps', t => { const layer = new PolygonLayer({ data: FIXTURES.polygons.slice(0, 3), getPolygon: f => f, @@ -64,9 +64,9 @@ test('ShadowPass#getModuleParameters', t => { }); const shadowPass = new ShadowPass(device, {pixelRatio: 1.0}); - const moduleParameters = shadowPass.getModuleParameters(layer); + const shaderModuleProps = shadowPass.getShaderModuleProps(layer); - t.equal(moduleParameters.shadow.drawToShadowMap, true, `ShadowPass has module parameters`); + t.equal(shaderModuleProps.shadow.drawToShadowMap, true, `ShadowPass has module parameters`); shadowPass.delete(); t.end(); }); diff --git a/test/modules/extensions/collision-filter/collision-filter-effect.spec.ts b/test/modules/extensions/collision-filter/collision-filter-effect.spec.ts index e1cd9c70312..a634c609633 100644 --- a/test/modules/extensions/collision-filter/collision-filter-effect.spec.ts +++ b/test/modules/extensions/collision-filter/collision-filter-effect.spec.ts @@ -117,20 +117,20 @@ test('CollisionFilterEffect#update', t => { }; preRenderWithLayers([TEST_LAYER], 'Initial render'); - let parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER).collision; + let parameters = collisionFilterEffect.getShaderModuleProps(TEST_LAYER).collision; t.ok(parameters.collisionFBO, 'collision map is in parameters'); t.ok(parameters.dummyCollisionMap, 'dummy collision map is in parameters'); preRenderWithLayers([TEST_LAYER, TEST_LAYER_2], 'Add second collision layer'); - parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER).collision; + parameters = collisionFilterEffect.getShaderModuleProps(TEST_LAYER).collision; t.ok(parameters.collisionFBO, 'collision map is in parameters'); t.ok(parameters.dummyCollisionMap, 'dummy collision map is in parameters'); - parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER_2).collision; + parameters = collisionFilterEffect.getShaderModuleProps(TEST_LAYER_2).collision; t.ok(parameters.collisionFBO, 'collision map is in parameters'); t.ok(parameters.dummyCollisionMap, 'dummy collision map is in parameters'); preRenderWithLayers([TEST_LAYER_2], 'Remove first layer'); - parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER_2).collision; + parameters = collisionFilterEffect.getShaderModuleProps(TEST_LAYER_2).collision; t.ok(parameters.collisionFBO, 'collision map is in parameters'); t.ok(parameters.dummyCollisionMap, 'dummy collision map is in parameters'); @@ -138,10 +138,10 @@ test('CollisionFilterEffect#update', t => { [TEST_LAYER_2, TEST_LAYER_DIFFERENT_GROUP], 'Add layer with different collision group' ); - parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER_2).collision; + parameters = collisionFilterEffect.getShaderModuleProps(TEST_LAYER_2).collision; t.ok(parameters.collisionFBO, 'collision map is in parameters'); t.ok(parameters.dummyCollisionMap, 'dummy collision map is in parameters'); - parameters = collisionFilterEffect.getModuleParameters(TEST_LAYER_DIFFERENT_GROUP).collision; + parameters = collisionFilterEffect.getShaderModuleProps(TEST_LAYER_DIFFERENT_GROUP).collision; t.ok(parameters.collisionFBO, 'collision map is in parameters'); t.ok(parameters.dummyCollisionMap, 'dummy collision map is in parameters'); diff --git a/test/modules/extensions/collision-filter/collision-filter-pass.spec.ts b/test/modules/extensions/collision-filter/collision-filter-pass.spec.ts index 1ddae91767b..87342d7951c 100644 --- a/test/modules/extensions/collision-filter/collision-filter-pass.spec.ts +++ b/test/modules/extensions/collision-filter/collision-filter-pass.spec.ts @@ -7,27 +7,27 @@ import test from 'tape-promise/tape'; import CollisionFilterPass from '@deck.gl/extensions/collision-filter/collision-filter-pass'; import {device} from '@deck.gl/test-utils'; -test('CollisionFilterPass#getModuleParameters', t => { +test('CollisionFilterPass#getShaderModuleProps', t => { const collisionFilterPass = new CollisionFilterPass(device); - const moduleParameters = collisionFilterPass.getModuleParameters(); + const shaderModuleProps = collisionFilterPass.getShaderModuleProps(); t.equal( - moduleParameters.collision.drawToCollisionMap, + shaderModuleProps.collision.drawToCollisionMap, true, `CollisionFilterPass has drawToCollisionMap module parameter` ); t.equal( - moduleParameters.picking.isActive, + shaderModuleProps.picking.isActive, 1, `CollisionFilterPass has picking.isActive module parameter` ); t.equal( - moduleParameters.picking.isAttribute, + shaderModuleProps.picking.isAttribute, false, `CollisionFilterPass has picking.isAttribute module parameter` ); t.deepEqual( - moduleParameters.lighting, + shaderModuleProps.lighting, {enabled: false}, `CollisionFilterPass disables lighting module` ); diff --git a/test/modules/extensions/mask/mask-effect.spec.ts b/test/modules/extensions/mask/mask-effect.spec.ts index 317000f2694..08e7b4ccc42 100644 --- a/test/modules/extensions/mask/mask-effect.spec.ts +++ b/test/modules/extensions/mask/mask-effect.spec.ts @@ -95,7 +95,7 @@ test('MaskEffect#update', t => { preRenderWithLayers([TEST_MASK_LAYER, TEST_LAYER], 'Initial render'); - let parameters = maskEffect.getModuleParameters(TEST_LAYER).mask; + let parameters = maskEffect.getShaderModuleProps(TEST_LAYER).mask; t.is(parameters.maskMap, maskEffect.maskMap, 'Mask map is in parameters'); let mask = parameters.maskChannels['test-mask-layer']; t.is(mask?.index, 0, 'Mask is rendered in channel 0'); @@ -104,7 +104,7 @@ test('MaskEffect#update', t => { preRenderWithLayers([TEST_MASK_LAYER, TEST_LAYER, TEST_MASK_LAYER2], 'Add second mask'); - parameters = maskEffect.getModuleParameters(TEST_LAYER).mask; + parameters = maskEffect.getShaderModuleProps(TEST_LAYER).mask; mask = parameters.maskChannels['test-mask-layer']; t.is(mask?.index, 0, 'Mask is rendered in channel 0'); t.is(mask?.bounds, bounds, 'Using cached mask bounds'); @@ -115,7 +115,7 @@ test('MaskEffect#update', t => { preRenderWithLayers([TEST_LAYER, TEST_MASK_LAYER2], 'Remove first mask'); - parameters = maskEffect.getModuleParameters(TEST_LAYER).mask; + parameters = maskEffect.getShaderModuleProps(TEST_LAYER).mask; mask = parameters.maskChannels['test-mask-layer']; t.notOk(mask, 'Mask is removed'); mask = parameters.maskChannels['test-mask-layer-2']; @@ -127,7 +127,7 @@ test('MaskEffect#update', t => { 'Update second mask, add third' ); - parameters = maskEffect.getModuleParameters(TEST_LAYER).mask; + parameters = maskEffect.getShaderModuleProps(TEST_LAYER).mask; mask = parameters.maskChannels['test-mask-layer-2']; t.is(mask?.index, 1, 'Second mask is rendered in channel 1'); t.not(mask?.bounds, bounds, 'Second mask is updated'); @@ -165,14 +165,14 @@ test('MaskEffect#coordinates', t => { preRenderWithLayers([TEST_MASK_LAYER, TEST_LAYER], 'Initial render'); - let parameters = maskEffect.getModuleParameters(TEST_LAYER).mask; + let parameters = maskEffect.getShaderModuleProps(TEST_LAYER).mask; let mask = parameters.maskChannels['test-mask-layer']; t.same(mask?.coordinateOrigin, [0, 0, 0], 'Mask has correct coordinate origin'); t.is(mask?.coordinateSystem, COORDINATE_SYSTEM.DEFAULT, 'Mask has correct coordinate system'); preRenderWithLayers([TEST_MASK_LAYER_CARTESIAN, TEST_LAYER], 'Update to cartesion coordinates'); - parameters = maskEffect.getModuleParameters(TEST_LAYER).mask; + parameters = maskEffect.getShaderModuleProps(TEST_LAYER).mask; mask = parameters.maskChannels['test-mask-layer']; t.same(mask?.coordinateOrigin, [1, 2, 3], 'Mask has correct coordinate origin'); t.is(mask?.coordinateSystem, COORDINATE_SYSTEM.CARTESIAN, 'Mask has correct coordinate system'); From 453b99b47a31a1795c8346cf08caa91a5ac1140f Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Sun, 29 Sep 2024 10:36:12 -0700 Subject: [PATCH 6/9] fix tests --- modules/core/src/lib/layer.ts | 10 ++++++ modules/core/src/passes/pick-layers-pass.ts | 7 +++- .../extensions/src/terrain/terrain-effect.ts | 2 -- .../extensions/src/terrain/terrain-pass.ts | 8 +++++ .../src/terrain/terrain-picking-pass.ts | 8 +++++ test/modules/core/passes/shadow-pass.spec.ts | 6 ++-- .../core/shaderlib/shadow/shadow.spec.ts | 34 ++++++++----------- 7 files changed, 50 insertions(+), 25 deletions(-) diff --git a/modules/core/src/lib/layer.ts b/modules/core/src/lib/layer.ts index 420caa5bbaf..f67bc6be166 100644 --- a/modules/core/src/lib/layer.ts +++ b/modules/core/src/lib/layer.ts @@ -321,6 +321,15 @@ export default abstract class Layer extends Component< return (state && (state.models || (state.model && [state.model]))) || []; } + // TODO deprecate in favour of setShaderModuleProps + /** Update shader module parameters */ + setModuleParameters(moduleParameters: any): void { + for (const model of this.getModels()) { + // HACK as fp64 is not yet ported to UBO + model.uniforms = {ONE: 1}; + } + } + /** Update shader input parameters */ setShaderModuleProps(...props: Parameters): void { for (const model of this.getModels()) { @@ -1047,6 +1056,7 @@ export default abstract class Layer extends Component< try { // TODO/ib - hack move to luma Model.draw if (shaderModuleProps) { + this.setModuleParameters({}); this.setShaderModuleProps(shaderModuleProps); } diff --git a/modules/core/src/passes/pick-layers-pass.ts b/modules/core/src/passes/pick-layers-pass.ts index 8edbaf2a88f..a2802840bb5 100644 --- a/modules/core/src/passes/pick-layers-pass.ts +++ b/modules/core/src/passes/pick-layers-pass.ts @@ -6,6 +6,7 @@ import LayersPass, {LayersPassRenderOptions, RenderStats, Rect} from './layers-p import type {Framebuffer, RenderPipelineParameters} from '@luma.gl/core'; import log from '../utils/log'; +import type {Effect} from '../lib/effect'; import type Viewport from '../viewports/viewport'; import type Layer from '../lib/layer'; @@ -115,7 +116,11 @@ export default class PickLayersPass extends LayersPass { ); } - protected getShaderModuleProps() { + protected getShaderModuleProps( + layer: Layer, + effects: Effect[] | undefined, + otherShaderModuleProps: Record + ): any { return { picking: { isActive: 1, diff --git a/modules/extensions/src/terrain/terrain-effect.ts b/modules/extensions/src/terrain/terrain-effect.ts index d22bf507194..2955ebf532a 100644 --- a/modules/extensions/src/terrain/terrain-effect.ts +++ b/modules/extensions/src/terrain/terrain-effect.ts @@ -141,7 +141,6 @@ export class TerrainEffect implements Effect { layers: terrainLayers, shaderModuleProps: { terrain: { - viewport, heightMapBounds: this.heightMap.bounds, dummyHeightMap: this.dummyHeightMap, drawToTerrainHeightMap: true @@ -204,7 +203,6 @@ export class TerrainEffect implements Effect { layers: drapeLayers, shaderModuleProps: { terrain: { - viewport, dummyHeightMap: this.dummyHeightMap, terrainSkipRender: false }, diff --git a/modules/extensions/src/terrain/terrain-pass.ts b/modules/extensions/src/terrain/terrain-pass.ts index bae47e319d7..da45506dd42 100644 --- a/modules/extensions/src/terrain/terrain-pass.ts +++ b/modules/extensions/src/terrain/terrain-pass.ts @@ -87,4 +87,12 @@ export class TerrainPass extends LayersPass { ...(layer.props.operation.includes('terrain') && TERRAIN_BLENDING) }; } + + getShaderModuleProps(layer: Layer, effects: any, otherShaderModuleProps: Record) { + return { + terrain: { + project: otherShaderModuleProps.project + } + }; + } } diff --git a/modules/extensions/src/terrain/terrain-picking-pass.ts b/modules/extensions/src/terrain/terrain-picking-pass.ts index 3658462742d..4db5f56f46a 100644 --- a/modules/extensions/src/terrain/terrain-picking-pass.ts +++ b/modules/extensions/src/terrain/terrain-picking-pass.ts @@ -82,4 +82,12 @@ export class TerrainPickingPass extends PickLayersPass { } return {...parameters, depthTest: false}; } + + getShaderModuleProps(layer: Layer, effects: any, otherShaderModuleProps: Record) { + return { + terrain: { + project: otherShaderModuleProps.project + } + }; + } } diff --git a/test/modules/core/passes/shadow-pass.spec.ts b/test/modules/core/passes/shadow-pass.spec.ts index ffe7cf112bb..d4e1e582b91 100644 --- a/test/modules/core/passes/shadow-pass.spec.ts +++ b/test/modules/core/passes/shadow-pass.spec.ts @@ -64,9 +64,11 @@ test('ShadowPass#getShaderModuleProps', t => { }); const shadowPass = new ShadowPass(device, {pixelRatio: 1.0}); - const shaderModuleProps = shadowPass.getShaderModuleProps(layer); + const shaderModuleProps = shadowPass.getShaderModuleProps(layer, [], { + project: {} + }); - t.equal(shaderModuleProps.shadow.drawToShadowMap, true, `ShadowPass has module parameters`); + t.equal(shaderModuleProps.shadow.drawToShadowMap, true, `ShadowPass has module props`); shadowPass.delete(); t.end(); }); diff --git a/test/modules/core/shaderlib/shadow/shadow.spec.ts b/test/modules/core/shaderlib/shadow/shadow.spec.ts index 582d7a32313..ce581cfe5a4 100644 --- a/test/modules/core/shaderlib/shadow/shadow.spec.ts +++ b/test/modules/core/shaderlib/shadow/shadow.spec.ts @@ -132,7 +132,7 @@ test('shadow#getUniforms', t => { }); let uniforms = shadow.getUniforms({ - viewport, + project: {viewport}, shadowMatrices: [viewMatrix], drawToShadowMap: true, dummyShadowMaps: [true] @@ -157,15 +157,12 @@ test('shadow#getUniforms', t => { // LNGLAT_AUTO_OFFSET mode viewport = TEST_VIEWPORT2; - uniforms = shadow.getUniforms( - { - viewport, - shadowMatrices: [viewMatrix], - drawToShadowMap: true, - dummyShadowMaps: [true] - }, - project.getUniforms({viewport}) - ); + uniforms = shadow.getUniforms({ + project: {viewport}, + shadowMatrices: [viewMatrix], + drawToShadowMap: true, + dummyShadowMaps: [true] + }); for (const value of TEST_CASE2) { const result = uniforms.viewProjectionMatrix0.transform(value.xyz); @@ -184,18 +181,15 @@ test('shadow#getUniforms', t => { // Non-Geospatial Identity Mode viewport = TEST_VIEWPORT3; - uniforms = shadow.getUniforms( - { + uniforms = shadow.getUniforms({ + project: { viewport, - shadowMatrices: [viewMatrix], - drawToShadowMap: true, - dummyShadowMaps: [true] - }, - { - center: [0, 0, 0, 0], coordinateSystem: COORDINATE_SYSTEM.CARTESIAN - } - ); + }, + shadowMatrices: [viewMatrix], + drawToShadowMap: true, + dummyShadowMaps: [true] + }); for (const value of TEST_CASE3) { const result = uniforms.viewProjectionMatrix0.transform(value.xyz); From 0432b7ae953dcda06e70c4c48efc18162be146ec Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Mon, 30 Sep 2024 10:12:37 +0200 Subject: [PATCH 7/9] Fix collision vertex discard --- modules/extensions/src/collision-filter/shader-module.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/extensions/src/collision-filter/shader-module.ts b/modules/extensions/src/collision-filter/shader-module.ts index 1e1658d5fe8..0b699739ac1 100644 --- a/modules/extensions/src/collision-filter/shader-module.ts +++ b/modules/extensions/src/collision-filter/shader-module.ts @@ -72,7 +72,7 @@ const inject = { collision_fade = collision_isVisible(collision_texCoords, geometry.pickingColor / 255.0); if (collision_fade < 0.0001) { // Position outside clip space bounds to discard - // position = vec4(0.0, 0.0, 2.0, 1.0); + position = vec4(0.0, 0.0, 2.0, 1.0); } } `, @@ -106,7 +106,7 @@ const getCollisionUniforms = ( } const {enabled, collisionFBO, drawToCollisionMap, dummyCollisionMap} = opts; return { - enabled, + enabled: enabled && !Boolean(drawToCollisionMap), sort: Boolean(drawToCollisionMap), collision_texture: !drawToCollisionMap && collisionFBO ? collisionFBO.colorAttachments[0] : dummyCollisionMap From 073bfd1148a1bde81c4b8384eaa0f8f5efb0e80d Mon Sep 17 00:00:00 2001 From: Felix Palmer Date: Mon, 30 Sep 2024 10:27:14 +0200 Subject: [PATCH 8/9] Lint --- modules/extensions/src/collision-filter/shader-module.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/extensions/src/collision-filter/shader-module.ts b/modules/extensions/src/collision-filter/shader-module.ts index 0b699739ac1..39346781e0a 100644 --- a/modules/extensions/src/collision-filter/shader-module.ts +++ b/modules/extensions/src/collision-filter/shader-module.ts @@ -106,7 +106,7 @@ const getCollisionUniforms = ( } const {enabled, collisionFBO, drawToCollisionMap, dummyCollisionMap} = opts; return { - enabled: enabled && !Boolean(drawToCollisionMap), + enabled: enabled && !drawToCollisionMap, sort: Boolean(drawToCollisionMap), collision_texture: !drawToCollisionMap && collisionFBO ? collisionFBO.colorAttachments[0] : dummyCollisionMap From 479f1c70802be4a8dd832344d4c8f115bba845ff Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Mon, 30 Sep 2024 10:08:24 -0700 Subject: [PATCH 9/9] Remove reference of moduleSettings --- .../aggregation-layers/aggregator.md | 2 +- .../src/common/aggregation-layer.ts | 7 +++++-- .../src/common/aggregator/aggregator.ts | 2 +- .../gpu-aggregator/webgl-aggregator.ts | 17 ++++------------- .../gpu-aggregator/webgl-bin-sorter.ts | 11 +++++------ test/data/grid-aggregation-data.js | 2 +- .../common/webgl-aggregator.spec.ts | 4 ++-- 7 files changed, 19 insertions(+), 26 deletions(-) diff --git a/docs/api-reference/aggregation-layers/aggregator.md b/docs/api-reference/aggregation-layers/aggregator.md index d91c442b6af..72b90241b68 100644 --- a/docs/api-reference/aggregation-layers/aggregator.md +++ b/docs/api-reference/aggregation-layers/aggregator.md @@ -86,7 +86,7 @@ aggregator.update(); Called before the result buffers are drawn to screen. Certain types of aggregations are dependent on render time context and this is alternative opportunity to update just-in-time. ```ts -aggregator.preDraw({moduleSettings: ...}); +aggregator.preDraw(); ``` #### `getBin` {#getbin} diff --git a/modules/aggregation-layers/src/common/aggregation-layer.ts b/modules/aggregation-layers/src/common/aggregation-layer.ts index 65b96409b1f..9d4ab4f4ade 100644 --- a/modules/aggregation-layers/src/common/aggregation-layer.ts +++ b/modules/aggregation-layers/src/common/aggregation-layer.ts @@ -87,11 +87,14 @@ export default abstract class AggregationLayer< } draw({shaderModuleProps}) { - // GPU aggregation needs `moduleSettings` for projection/filter uniforms which are only accessible at draw time + // GPU aggregation needs `shaderModuleProps` for projection/filter uniforms which are only accessible at draw time // GPUAggregator's Buffers are pre-allocated during `update()` and passed down to the sublayer attributes in renderLayers() // Although the Buffers have been bound to the sublayer's Model, their content are not populated yet // GPUAggregator.preDraw() is called in the draw cycle here right before Buffers are used by sublayer.draw() - this.state.aggregator.preDraw({moduleSettings: shaderModuleProps}); + const {aggregator} = this.state; + // @ts-expect-error only used by GPU aggregators + aggregator.setProps({shaderModuleProps}); + aggregator.preDraw(); } // override CompositeLayer._getAttributeManager to create AttributeManager instance diff --git a/modules/aggregation-layers/src/common/aggregator/aggregator.ts b/modules/aggregation-layers/src/common/aggregator/aggregator.ts index 651d6861202..41ef6d960c6 100644 --- a/modules/aggregation-layers/src/common/aggregator/aggregator.ts +++ b/modules/aggregation-layers/src/common/aggregator/aggregator.ts @@ -66,7 +66,7 @@ export interface Aggregator { update(): void; /** Called before layer is drawn to screen. */ - preDraw(params?: {moduleSettings: any}): void; + preDraw(): void; /** Dispose all allocated resources */ destroy(): void; diff --git a/modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-aggregator.ts b/modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-aggregator.ts index 95bd622b76d..70879da9293 100644 --- a/modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-aggregator.ts +++ b/modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-aggregator.ts @@ -42,7 +42,7 @@ type WebGLAggregationProps = AggregationProps & { */ binIdRange: [start: number, end: number][]; /** Context props passed to the shader modules */ - moduleSettings?: ModelProps['moduleSettings']; + shaderModuleProps?: Record; }; /** An Aggregator implementation that calculates aggregation on the GPU */ @@ -221,8 +221,8 @@ export class WebGLAggregator implements Aggregator { } this.binSorter.setModelProps({attributes: attributeBuffers, constantAttributes}); } - if (props.moduleSettings) { - this.binSorter.setModelProps({moduleSettings: props.moduleSettings}); + if (props.shaderModuleProps) { + this.binSorter.setModelProps({shaderModuleProps: props.shaderModuleProps}); } Object.assign(this.props, props); @@ -245,20 +245,11 @@ export class WebGLAggregator implements Aggregator { update() {} /** Run aggregation */ - preDraw( - /** Parameters only available at runtime */ - opts: { - moduleSettings: any; - } - ) { + preDraw() { if (!this.needsUpdate.some(Boolean)) { return; } - if (opts.moduleSettings) { - this.binSorter.setModelProps({moduleSettings: opts.moduleSettings}); - } - const {operations} = this.props; const operationsToUpdate = this.needsUpdate.map((needsUpdate, i) => needsUpdate ? operations[i] : null diff --git a/modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-bin-sorter.ts b/modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-bin-sorter.ts index 791255cf4af..15d0f6038f4 100644 --- a/modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-bin-sorter.ts +++ b/modules/aggregation-layers/src/common/aggregator/gpu-aggregator/webgl-bin-sorter.ts @@ -89,10 +89,9 @@ export class WebGLBinSorter { } setModelProps( - props: Pick< - ModelProps, - 'moduleSettings' | 'vertexCount' | 'uniforms' | 'attributes' | 'constantAttributes' - > + props: Pick & { + shaderModuleProps?: Record; + } ) { const model = this.model; if (props.attributes) { @@ -104,8 +103,8 @@ export class WebGLBinSorter { if (props.vertexCount !== undefined) { model.setVertexCount(props.vertexCount); } - if (props.moduleSettings) { - model.shaderInputs.setProps(props.moduleSettings); + if (props.shaderModuleProps) { + model.shaderInputs.setProps(props.shaderModuleProps); } } diff --git a/test/data/grid-aggregation-data.js b/test/data/grid-aggregation-data.js index 8bdbd9e7cd0..dc600b6a8ce 100644 --- a/test/data/grid-aggregation-data.js +++ b/test/data/grid-aggregation-data.js @@ -81,7 +81,7 @@ const fixture = { } }, cellSize: [25, 25], - moduleSettings: {viewport}, + shaderModuleProps: {viewport}, projectPoints: true, translation: [1, -1], scaling: [width / 2, -height / 2, 1], diff --git a/test/modules/aggregation-layers/common/webgl-aggregator.spec.ts b/test/modules/aggregation-layers/common/webgl-aggregator.spec.ts index 9d984477edb..e4b8ee85b03 100644 --- a/test/modules/aggregation-layers/common/webgl-aggregator.spec.ts +++ b/test/modules/aggregation-layers/common/webgl-aggregator.spec.ts @@ -140,7 +140,7 @@ test('WebGLAggregator#1D', t => { }); aggregator.update(); - aggregator.preDraw({moduleSettings: {}}); + aggregator.preDraw(); t.is(aggregator.binCount, 15, 'binCount'); @@ -248,7 +248,7 @@ test('WebGLAggregator#2D', t => { }); aggregator.update(); - aggregator.preDraw({moduleSettings: {}}); + aggregator.preDraw(); t.is(aggregator.binCount, 20, 'binCount');