UNPKG

@luma.gl/shadertools

Version:

Shader module system for luma.gl

93 lines (74 loc) 2.69 kB
import { MODULE_INJECTORS_VS, MODULE_INJECTORS_FS } from '../modules/module-injectors'; import { VERTEX_SHADER, FRAGMENT_SHADER } from './constants'; import { assert } from '../utils'; const MODULE_INJECTORS = { [VERTEX_SHADER]: MODULE_INJECTORS_VS, [FRAGMENT_SHADER]: MODULE_INJECTORS_FS }; export const DECLARATION_INJECT_MARKER = '__LUMA_INJECT_DECLARATIONS__'; const REGEX_START_OF_MAIN = /void\s+main\s*\([^)]*\)\s*\{\n?/; const REGEX_END_OF_MAIN = /}\n?[^{}]*$/; const fragments = []; export default function injectShader(source, type, inject) { let injectStandardStubs = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; const isVertex = type === VERTEX_SHADER; for (const key in inject) { const fragmentData = inject[key]; fragmentData.sort((a, b) => a.order - b.order); fragments.length = fragmentData.length; for (let i = 0, len = fragmentData.length; i < len; ++i) { fragments[i] = fragmentData[i].injection; } const fragmentString = "".concat(fragments.join('\n'), "\n"); switch (key) { case 'vs:#decl': if (isVertex) { source = source.replace(DECLARATION_INJECT_MARKER, fragmentString); } break; case 'vs:#main-start': if (isVertex) { source = source.replace(REGEX_START_OF_MAIN, match => match + fragmentString); } break; case 'vs:#main-end': if (isVertex) { source = source.replace(REGEX_END_OF_MAIN, match => fragmentString + match); } break; case 'fs:#decl': if (!isVertex) { source = source.replace(DECLARATION_INJECT_MARKER, fragmentString); } break; case 'fs:#main-start': if (!isVertex) { source = source.replace(REGEX_START_OF_MAIN, match => match + fragmentString); } break; case 'fs:#main-end': if (!isVertex) { source = source.replace(REGEX_END_OF_MAIN, match => fragmentString + match); } break; default: source = source.replace(key, match => match + fragmentString); } } source = source.replace(DECLARATION_INJECT_MARKER, ''); if (injectStandardStubs) { source = source.replace(/\}\s*$/, match => match + MODULE_INJECTORS[type]); } return source; } export function combineInjects(injects) { const result = {}; assert(Array.isArray(injects) && injects.length > 1); injects.forEach(inject => { for (const key in inject) { result[key] = result[key] ? "".concat(result[key], "\n").concat(inject[key]) : inject[key]; } }); return result; } //# sourceMappingURL=inject-shader.js.map