Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

shadertools: Resolve dependencies in ShaderInputs #2073

Merged
merged 3 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions modules/engine/src/shader-inputs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import type {UniformValue, Texture, Sampler} from '@luma.gl/core';
import {log} from '@luma.gl/core';
// import type {ShaderUniformType, UniformValue, UniformFormat, UniformInfoDevice, Texture, Sampler} from '@luma.gl/core';
import {_resolveModules, ShaderModuleInstance} from '@luma.gl/shadertools';
import {_getDependencyGraph, ShaderModuleInstance} from '@luma.gl/shadertools';

/** Minimal ShaderModule subset, we don't need shader code etc */
export type ShaderModuleInputs<
Expand Down Expand Up @@ -61,17 +61,20 @@ export class ShaderInputs<
* @param modules
*/
// @ts-expect-error Fix typings
constructor(modules: {[P in keyof ShaderPropsT]: ShaderModuleInputs<ShaderPropsT[P]>}) {
// TODO - get all dependencies from modules
const allModules = _resolveModules(Object.values(modules));
log.log(
1,
'Creating ShaderInputs with modules',
allModules.map(m => m.name)
)();
constructor(modules: {[P in keyof ShaderPropsT]?: ShaderModuleInputs<ShaderPropsT[P]>}) {
// Extract modules with dependencies and resolve
const allModules = {};
_getDependencyGraph({
felixpalmer marked this conversation as resolved.
Show resolved Hide resolved
modules: Object.values(modules).filter(module => module.dependencies),
level: 0,
moduleMap: allModules,
moduleDepth: {}
});
modules = {...modules, ...allModules};
log.log(1, 'Creating ShaderInputs with modules', Object.keys(modules))();

// Store the module definitions and create storage for uniform values and binding values, per module
this.modules = modules;
this.modules = modules as typeof this.modules;
felixpalmer marked this conversation as resolved.
Show resolved Hide resolved
this.moduleUniforms = {} as Record<keyof ShaderPropsT, Record<string, UniformValue>>;
this.moduleBindings = {} as Record<keyof ShaderPropsT, Record<string, Texture | Sampler>>;

Expand Down
31 changes: 31 additions & 0 deletions modules/engine/test/shader-inputs.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import test from 'tape-promise/tape';
import {picking} from '../../shadertools/src/index';
// import {_ShaderInputs as ShaderInputs} from '@luma.gl/engine';
import {ShaderInputs} from '../src/shader-inputs';
import {ShaderModule} from '@luma.gl/shadertools';

test('ShaderInputs#picking', t => {
const shaderInputsUntyped = new ShaderInputs({picking});
Expand Down Expand Up @@ -62,3 +63,33 @@ test('ShaderInputs#picking prop merge', t => {

t.end();
});

test('ShaderInputs#dependencies', t => {
type CustomProps = {color: number[]};
const custom: ShaderModule<CustomProps> = {
name: 'custom',
dependencies: [picking],
uniformTypes: {
color: 'vec3<f32>'
}
};

const shaderInputs = new ShaderInputs<{
custom: CustomProps;
picking: typeof picking.props;
}>({custom});
t.deepEqual(Object.keys(shaderInputs.modules), ['custom', 'picking']);

shaderInputs.setProps({
custom: {color: [255, 0, 0]},
picking: {highlightedObjectColor: [1, 2, 3]}
});
t.deepEqual(shaderInputs.moduleUniforms.custom.color, [255, 0, 0], 'custom color updated');
t.deepEqual(
shaderInputs.moduleUniforms.picking.highlightedObjectColor,
[1, 2, 3],
'highlight object color updated'
);

t.end();
});
11 changes: 8 additions & 3 deletions modules/shadertools/src/lib/shader-assembly/resolve-modules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ function getShaderDependencies(modules: ShaderModuleInstance[]): ShaderModuleIns
.map(name => moduleMap[name]);
}

type AbstractModule = {
felixpalmer marked this conversation as resolved.
Show resolved Hide resolved
name: string;
dependencies: AbstractModule[];
};

/**
* Recursively checks module dependencies to calculate dependency level of each module.
*
Expand All @@ -48,10 +53,10 @@ function getShaderDependencies(modules: ShaderModuleInstance[]): ShaderModuleIns
* @return - Map of module name to its level
*/
// Adds another level of dependencies to the result map
export function getDependencyGraph(options: {
modules: ShaderModuleInstance[];
export function getDependencyGraph<T extends AbstractModule>(options: {
modules: T[];
level: number;
moduleMap: Record<string, ShaderModuleInstance>;
moduleMap: Record<string, T>;
moduleDepth: Record<string, number>;
}) {
const {modules, level, moduleMap, moduleDepth} = options;
Expand Down
Loading