UNPKG

@luma.gl/shadertools

Version:

Shader module system for luma.gl

94 lines (73 loc) 5.14 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.default = transpileShader; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; } function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); } function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; } function testVariable(qualifier) { return new RegExp("\\b".concat(qualifier, "[ \\t]+(\\w+[ \\t]+\\w+(\\[\\w+\\])?;)"), 'g'); } var 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(']]; var ES300_VERTEX_REPLACEMENTS = [].concat(ES300_REPLACEMENTS, [[testVariable('attribute'), 'in $1'], [testVariable('varying'), 'out $1']]); var ES300_FRAGMENT_REPLACEMENTS = [].concat(ES300_REPLACEMENTS, [[testVariable('varying'), 'in $1']]); var ES100_REPLACEMENTS = [[/^#version[ \t]+300[ \t]+es/, '#version 100'], [/\btexture(2D|2DProj|Cube)Lod\(/g, 'texture$1LodEXT('], [/\btexture\(/g, 'texture2D('], [/\btextureLod\(/g, 'texture2DLodEXT(']]; var ES100_VERTEX_REPLACEMENTS = [].concat(ES100_REPLACEMENTS, [[testVariable('in'), 'attribute $1'], [testVariable('out'), 'varying $1']]); var ES100_FRAGMENT_REPLACEMENTS = [].concat(ES100_REPLACEMENTS, [[testVariable('in'), 'varying $1']]); var ES100_FRAGMENT_OUTPUT_NAME = 'gl_FragColor'; var ES300_FRAGMENT_OUTPUT_REGEX = /\bout[ \t]+vec4[ \t]+(\w+)[ \t]*;\n?/; var REGEX_START_OF_MAIN = /void\s+main\s*\([^)]*\)\s*\{\n?/; 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) { var _iterator = _createForOfIteratorHelper(replacements), _step; try { for (_iterator.s(); !(_step = _iterator.n()).done;) { var _step$value = (0, _slicedToArray2.default)(_step.value, 2), pattern = _step$value[0], replacement = _step$value[1]; source = source.replace(pattern, replacement); } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } return source; } function convertFragmentShaderTo300(source) { source = convertShader(source, ES300_FRAGMENT_REPLACEMENTS); var outputMatch = source.match(ES300_FRAGMENT_OUTPUT_REGEX); if (outputMatch) { var outputName = outputMatch[1]; source = source.replace(new RegExp("\\b".concat(ES100_FRAGMENT_OUTPUT_NAME, "\\b"), 'g'), outputName); } else { var _outputName = 'fragmentColor'; source = source.replace(REGEX_START_OF_MAIN, function (match) { return "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); var outputMatch = source.match(ES300_FRAGMENT_OUTPUT_REGEX); if (outputMatch) { var 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