UNPKG

@luma.gl/shadertools

Version:

Shader module system for luma.gl

61 lines (50 loc) 2.9 kB
function testVariable(qualifier) { return new RegExp("\\b".concat(qualifier, "[ \\t]+(\\w+[ \\t]+\\w+(\\[\\w+\\])?;)"), 'g'); } const ES300_REPLACEMENTS = [[/^(#version[ \t]+(100|300[ \t]+es))?[ \t]*\n/, '#version 300 es\n'], [/\btexture(2D|2DProj|Cube)Lod(EXT)?\(/g, 'textureLod('], [/\btexture(2D|2DProj|Cube)(EXT)?\(/g, 'texture(']]; const ES300_VERTEX_REPLACEMENTS = [...ES300_REPLACEMENTS, [testVariable('attribute'), 'in $1'], [testVariable('varying'), 'out $1']]; const ES300_FRAGMENT_REPLACEMENTS = [...ES300_REPLACEMENTS, [testVariable('varying'), 'in $1']]; const ES100_REPLACEMENTS = [[/^#version[ \t]+300[ \t]+es/, '#version 100'], [/\btexture(2D|2DProj|Cube)Lod\(/g, 'texture$1LodEXT('], [/\btexture\(/g, 'texture2D('], [/\btextureLod\(/g, 'texture2DLodEXT(']]; const ES100_VERTEX_REPLACEMENTS = [...ES100_REPLACEMENTS, [testVariable('in'), 'attribute $1'], [testVariable('out'), 'varying $1']]; const ES100_FRAGMENT_REPLACEMENTS = [...ES100_REPLACEMENTS, [testVariable('in'), 'varying $1']]; const ES100_FRAGMENT_OUTPUT_NAME = 'gl_FragColor'; const ES300_FRAGMENT_OUTPUT_REGEX = /\bout[ \t]+vec4[ \t]+(\w+)[ \t]*;\n?/; const REGEX_START_OF_MAIN = /void\s+main\s*\([^)]*\)\s*\{\n?/; export default function transpileShader(source, targetGLSLVersion, isVertex) { switch (targetGLSLVersion) { case 300: return isVertex ? convertShader(source, ES300_VERTEX_REPLACEMENTS) : convertFragmentShaderTo300(source); case 100: return isVertex ? convertShader(source, ES100_VERTEX_REPLACEMENTS) : convertFragmentShaderTo100(source); default: throw new Error("unknown GLSL version ".concat(targetGLSLVersion)); } } function convertShader(source, replacements) { for (const [pattern, replacement] of replacements) { source = source.replace(pattern, replacement); } return source; } function convertFragmentShaderTo300(source) { source = convertShader(source, ES300_FRAGMENT_REPLACEMENTS); const outputMatch = source.match(ES300_FRAGMENT_OUTPUT_REGEX); if (outputMatch) { const outputName = outputMatch[1]; source = source.replace(new RegExp("\\b".concat(ES100_FRAGMENT_OUTPUT_NAME, "\\b"), 'g'), outputName); } else { const outputName = 'fragmentColor'; source = source.replace(REGEX_START_OF_MAIN, match => "out vec4 ".concat(outputName, ";\n").concat(match)).replace(new RegExp("\\b".concat(ES100_FRAGMENT_OUTPUT_NAME, "\\b"), 'g'), outputName); } return source; } function convertFragmentShaderTo100(source) { source = convertShader(source, ES100_FRAGMENT_REPLACEMENTS); const outputMatch = source.match(ES300_FRAGMENT_OUTPUT_REGEX); if (outputMatch) { const outputName = outputMatch[1]; source = source.replace(ES300_FRAGMENT_OUTPUT_REGEX, '').replace(new RegExp("\\b".concat(outputName, "\\b"), 'g'), ES100_FRAGMENT_OUTPUT_NAME); } return source; } //# sourceMappingURL=transpile-shader.js.map