Skip to content

Commit

Permalink
Register default shader module with Deck (#8682)
Browse files Browse the repository at this point in the history
  • Loading branch information
Pessimistress committed Mar 20, 2024
1 parent ecd78ec commit 3d57cf7
Show file tree
Hide file tree
Showing 21 changed files with 196 additions and 173 deletions.
16 changes: 5 additions & 11 deletions modules/core/src/effects/lighting/lighting-effect.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type {Device} from '@luma.gl/core';
import {ShaderAssembler} from '@luma.gl/shadertools';
import {Texture} from '@luma.gl/core';
import {AmbientLight} from './ambient-light';
import {DirectionalLight} from './directional-light';
Expand Down Expand Up @@ -42,7 +41,6 @@ export default class LightingEffect implements Effect {
private shadowPasses: ShadowPass[] = [];
private shadowMaps: Texture[] = [];
private dummyShadowMap: Texture | null = null;
private shaderAssembler?: ShaderAssembler;
private shadowMatrices?: Matrix4[];

constructor(props: LightingEffectProps = {}) {
Expand All @@ -51,12 +49,12 @@ export default class LightingEffect implements Effect {

setup(context: EffectContext) {
this.context = context;
const {device} = context;
const {device, deck} = context;

if (this.shadow && !this.dummyShadowMap) {
this._createShadowPasses(device);
this.shaderAssembler = ShaderAssembler.getDefaultShaderAssembler();
this.shaderAssembler.addDefaultModule(shadow);

deck._addDefaultShaderModule(shadow);

this.dummyShadowMap = device.createTexture({
width: 1,
Expand Down Expand Up @@ -154,7 +152,7 @@ export default class LightingEffect implements Effect {
return parameters;
}

cleanup(): void {
cleanup(context: EffectContext): void {
for (const shadowPass of this.shadowPasses) {
shadowPass.delete();
}
Expand All @@ -164,11 +162,7 @@ export default class LightingEffect implements Effect {
if (this.dummyShadowMap) {
this.dummyShadowMap.destroy();
this.dummyShadowMap = null;
}

if (this.shaderAssembler) {
this.shaderAssembler.removeDefaultModule(shadow);
this.shaderAssembler = null!;
context.deck._removeDefaultShaderModule(shadow);
}
}

Expand Down
2 changes: 1 addition & 1 deletion modules/core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
export {VERSION} from './lib/init';

// Import shaderlib to make sure shader modules are initialized
export {getPipelineFactory, getShaderAssembler} from './shaderlib/index';
export {getShaderAssembler} from './shaderlib/index';

// Core Library
export {COORDINATE_SYSTEM, OPERATION, UNIT} from './lib/constants';
Expand Down
9 changes: 9 additions & 0 deletions modules/core/src/lib/deck.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import {Timeline} from '@luma.gl/engine';
import {AnimationLoop} from '@luma.gl/engine';
import {GL} from '@luma.gl/constants';
import type {Device, DeviceProps, Framebuffer} from '@luma.gl/core';
import type {ShaderModule} from '@luma.gl/shadertools';

import {Stats} from '@probe.gl/stats';
import {EventManager} from 'mjolnir.js';
Expand Down Expand Up @@ -674,6 +675,14 @@ export default class Deck<ViewsT extends ViewOrViews = ViewOrViews> {
this.effectManager!.addDefaultEffect(effect);
}

_addDefaultShaderModule(module: ShaderModule) {
this.layerManager!.addDefaultShaderModule(module);
}

_removeDefaultShaderModule(module: ShaderModule) {
this.layerManager?.removeDefaultShaderModule(module);
}

// Private Methods

private _pick(
Expand Down
42 changes: 36 additions & 6 deletions modules/core/src/lib/layer-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,8 @@

import type {Device, RenderPass} from '@luma.gl/core';
import {Timeline} from '@luma.gl/engine';
import type {PipelineFactory} from '@luma.gl/engine';
import {ShaderAssembler} from '@luma.gl/shadertools';
import {getPipelineFactory, getShaderAssembler} from '../shaderlib/index';
import type {ShaderAssembler, ShaderModule} from '@luma.gl/shadertools';
import {getShaderAssembler} from '../shaderlib/index';
import {LIFECYCLE} from '../lifecycle/constants';
import log from '../utils/log';
import debug from '../debug/index';
Expand All @@ -45,7 +44,7 @@ export type LayerContext = {
deck?: Deck;
device: Device;
shaderAssembler: ShaderAssembler;
pipelineFactory: PipelineFactory;
defaultShaderModules: ShaderModule[];
renderPass: RenderPass;
stats: Stats;
viewport: Viewport;
Expand Down Expand Up @@ -75,6 +74,8 @@ export default class LayerManager {
private _needsUpdate: string | false = false;
private _nextLayers: LayersList | null = null;
private _debug: boolean = false;
// This flag is separate from _needsUpdate because it can be set during an update and should trigger another full update
private _defaultShaderModulesChanged: boolean = false;

/**
* @param device
Expand Down Expand Up @@ -104,9 +105,8 @@ export default class LayerManager {
// @ts-expect-error
gl: device?.gl,
deck,
// Enabling luma.gl Program caching using private API (_cachePrograms)
shaderAssembler: getShaderAssembler(),
pipelineFactory: (device && getPipelineFactory(device))!,
defaultShaderModules: [],
renderPass: undefined!,
stats: stats || new Stats({id: 'deck.gl'}),
// Make sure context.viewport is not empty on the first layer initialization
Expand Down Expand Up @@ -156,6 +156,9 @@ export default class LayerManager {
// New layers array may be the same as the old one if `setProps` is called by React
return 'layers changed';
}
if (this._defaultShaderModulesChanged) {
return 'shader modules changed';
}
return this._needsUpdate;
}

Expand Down Expand Up @@ -242,6 +245,25 @@ export default class LayerManager {
}
};

/** Register a default shader module */
addDefaultShaderModule(module: ShaderModule) {
const {defaultShaderModules} = this.context;
if (!defaultShaderModules.find(m => m.name === module.name)) {
defaultShaderModules.push(module);
this._defaultShaderModulesChanged = true;
}
}

/** Deregister a default shader module */
removeDefaultShaderModule(module: ShaderModule) {
const {defaultShaderModules} = this.context;
const i = defaultShaderModules.findIndex(m => m.name === module.name);
if (i >= 0) {
defaultShaderModules.splice(i, 1);
this._defaultShaderModulesChanged = true;
}
}

private _handleError(stage: string, error: Error, layer: Layer) {
layer.raiseError(error, `${stage} of ${layer}`);
}
Expand All @@ -260,6 +282,14 @@ export default class LayerManager {
}
}

if (this._defaultShaderModulesChanged) {
for (const layer of oldLayers) {
layer.setNeedsUpdate();
layer.setChangeFlags({extensionsChanged: true});
}
this._defaultShaderModulesChanged = false;
}

// Allocate array for generated layers
const generatedLayers: Layer[] = [];

Expand Down
3 changes: 3 additions & 0 deletions modules/core/src/lib/layer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,9 @@ export default abstract class Layer<PropsT extends {} = {}> extends Component<
abstract initializeState(context: LayerContext): void;

getShaders(shaders: any): any {
shaders = mergeShaders(shaders, {
modules: this.context.defaultShaderModules
});
for (const extension of this.props.extensions) {
shaders = mergeShaders(shaders, extension.getShaders.call(this, extension));
}
Expand Down
5 changes: 2 additions & 3 deletions modules/core/src/passes/shadow-pass.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,8 +55,7 @@ export default class ShadowPass extends LayersPass {
{
depthRange: [0, 1],
depthTest: true,
blend: false,
clearColor: [1, 1, 1, 1]
blend: false
},
() => {
// @ts-expect-error TODO - assuming WebGL context
Expand All @@ -69,7 +68,7 @@ export default class ShadowPass extends LayersPass {
target.resize({width, height});
}

super.render({...params, target, pass: 'shadow'});
super.render({...params, target, pass: 'shadow', clearColor: [1, 1, 1, 1]});
}
);
}
Expand Down
6 changes: 0 additions & 6 deletions modules/core/src/shaderlib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,6 @@ export function getShaderAssembler() {
return shaderAssembler;
}

// TODO - is this really needed now that modules are registered on the ShaderAssembler
export function getPipelineFactory(device: Device) {
const pipelineFactory = PipelineFactory.getDefaultPipelineFactory(device);
return pipelineFactory;
}

export {picking, project, project32, gouraudLighting, phongLighting, shadow};

// Useful for custom shader modules
Expand Down
4 changes: 3 additions & 1 deletion modules/core/src/shaderlib/shadow/shadow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,9 @@ function createShadowUniforms(
if (!shadowEnabled || !opts.shadowMatrices || !opts.shadowMatrices.length) {
return {
shadow_uDrawShadowMap: false,
shadow_uUseShadowMap: false
shadow_uUseShadowMap: false,
shadow_uShadowMap0: opts.dummyShadowMap,
shadow_uShadowMap1: opts.dummyShadowMap
};
}
const uniforms = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export default class CollisionFilterEffect implements Effect {
}

// Detect if mask has rendered. TODO: better dependency system for Effects
const effects = allEffects?.filter(e => e.constructor === MaskEffect);
const effects = allEffects?.filter(e => e.useInPicking && preRenderStats[e.id]);
const maskEffectRendered = (preRenderStats['mask-effect'] as MaskPreRenderStats)?.didRender;

// Collect layers to render
Expand Down
10 changes: 5 additions & 5 deletions modules/extensions/src/terrain/terrain-effect.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {Texture} from '@luma.gl/core';
import {log, getShaderAssembler} from '@deck.gl/core';
import {log} from '@deck.gl/core';

import {terrainModule, TerrainModuleSettings} from './shader-module';
import {TerrainCover} from './terrain-cover';
Expand Down Expand Up @@ -28,7 +28,7 @@ export class TerrainEffect implements Effect {
/** One texture for each primitive terrain layer, into which the draped layers render */
private terrainCovers: Map<string, TerrainCover> = new Map();

setup({device}: EffectContext) {
setup({device, deck}: EffectContext) {
this.dummyHeightMap = device.createTexture({
width: 1,
height: 1,
Expand All @@ -43,7 +43,7 @@ export class TerrainEffect implements Effect {
log.warn('Terrain offset mode is not supported by this browser')();
}

getShaderAssembler().addDefaultModule(terrainModule);
deck._addDefaultShaderModule(terrainModule);
}

preRender(opts: PreRenderOptions): void {
Expand Down Expand Up @@ -95,7 +95,7 @@ export class TerrainEffect implements Effect {
};
}

cleanup(): void {
cleanup({deck}: EffectContext): void {
if (this.dummyHeightMap) {
this.dummyHeightMap.delete();
this.dummyHeightMap = undefined;
Expand All @@ -111,7 +111,7 @@ export class TerrainEffect implements Effect {
}
this.terrainCovers.clear();

getShaderAssembler().removeDefaultModule(terrainModule);
deck._removeDefaultShaderModule(terrainModule);
}

private _updateHeightMap(terrainLayers: Layer[], viewport: Viewport, opts: PreRenderOptions) {
Expand Down
1 change: 1 addition & 0 deletions modules/extensions/src/terrain/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export function createRenderTarget(
id: opts.id,
colorAttachments: [
device.createTexture({
id: opts.id,
...(opts.float && {
format: 'rgba32float',
type: GL.FLOAT
Expand Down
1 change: 0 additions & 1 deletion modules/main/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,6 @@ export {
Tesselator,
fp64LowPart,
createIterable,
getPipelineFactory,
getShaderAssembler
} from '@deck.gl/core';

Expand Down
6 changes: 5 additions & 1 deletion modules/test-utils/src/snapshot-test-runner.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@ const DEFAULT_TEST_CASE: SnapshotTestCase = {
// eslint-disable-line
},
onAfterRender: ({deck, layers, done}) => {
if (layers.every(layer => layer.isLoaded)) {
if (
// @ts-expect-error accessing private
!deck.layerManager?.needsUpdate() &&
layers.every(layer => layer.isLoaded)
) {
done(); // eslint-disable-line
}
},
Expand Down

0 comments on commit 3d57cf7

Please sign in to comment.