@luma.gl/shadertools
Version:
Shader module system for luma.gl
94 lines (73 loc) • 5.14 kB
JavaScript
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
;