UNPKG

@luma.gl/shadertools

Version:

Shader module system for luma.gl

90 lines 3.51 kB
// luma.gl // SPDX-License-Identifier: MIT // Copyright (c) vis.gl contributors import { initializeShaderModules } from "./shader-module.js"; /** * Takes a list of shader module names and returns a new list of * shader module names that includes all dependencies, sorted so * that modules that are dependencies of other modules come first. * * If the shader glsl code from the returned modules is concatenated * in the reverse order, it is guaranteed that all functions be resolved and * that all function and variable definitions come before use. * * @param modules - Array of modules (inline modules or module names) * @return - Array of modules */ export function getShaderModuleDependencies(modules) { initializeShaderModules(modules); const moduleMap = {}; const moduleDepth = {}; getDependencyGraph({ modules, level: 0, moduleMap, moduleDepth }); // Return a reverse sort so that dependencies come before the modules that use them const dependencies = Object.keys(moduleDepth) .sort((a, b) => moduleDepth[b] - moduleDepth[a]) .map(name => moduleMap[name]); initializeShaderModules(dependencies); return dependencies; } /** * Recursively checks module dependencies to calculate dependency level of each module. * * @param options.modules - Array of modules * @param options.level - Current level * @param options.moduleMap - * @param options.moduleDepth - Current level * @return - Map of module name to its level */ // Adds another level of dependencies to the result map export function getDependencyGraph(options) { const { modules, level, moduleMap, moduleDepth } = options; if (level >= 5) { throw new Error('Possible loop in shader dependency graph'); } // Update level on all current modules for (const module of modules) { moduleMap[module.name] = module; if (moduleDepth[module.name] === undefined || moduleDepth[module.name] < level) { moduleDepth[module.name] = level; } } // Recurse for (const module of modules) { if (module.dependencies) { getDependencyGraph({ modules: module.dependencies, level: level + 1, moduleMap, moduleDepth }); } } } /** * Takes a list of shader module names and returns a new list of * shader module names that includes all dependencies, sorted so * that modules that are dependencies of other modules come first. * * If the shader glsl code from the returned modules is concatenated * in the reverse order, it is guaranteed that all functions be resolved and * that all function and variable definitions come before use. * * @param modules - Array of modules (inline modules or module names) * @return - Array of modules */ export function getShaderDependencies(modules) { initializeShaderModules(modules); const moduleMap = {}; const moduleDepth = {}; getDependencyGraph({ modules, level: 0, moduleMap, moduleDepth }); // Return a reverse sort so that dependencies come before the modules that use them modules = Object.keys(moduleDepth) .sort((a, b) => moduleDepth[b] - moduleDepth[a]) .map(name => moduleMap[name]); initializeShaderModules(modules); return modules; } // DEPRECATED /** * Instantiate shader modules and resolve any dependencies * @deprecated Use getShaderDpendencies */ export function resolveModules(modules) { return getShaderDependencies(modules); } //# sourceMappingURL=shader-module-dependencies.js.map