123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138 |
- // Dependencies.
- var through = require('through2');
- var PluginError = require('plugin-error');
- let path = require('path');
- let fs = require('fs');
- /**
- * Template creating hidden ts file containing the shaders.
- */
- let tsShaderTemplate =
- `import { Effect } from "##EFFECTLOCATION_PLACEHOLDER##";
- ##INCLUDES_PLACEHOLDER##
- let name = '##NAME_PLACEHOLDER##';
- let shader = \`##SHADER_PLACEHOLDER##\`;
- Effect.##SHADERSTORE_PLACEHOLDER##[name] = shader;
- ##EXPORT_PLACEHOLDER##
- `;
- /**
- * Get the shaders name from their path.
- */
- function getShaderName(filename) {
- let parts = filename.split('.');
- if (parts[1] !== 'fx') {
- return parts[0] + (parts[1] === 'fragment' ? 'Pixel' : 'Vertex') + "Shader";
- } else {
- return parts[0];
- }
- }
- /**
- * Get the shaders included in the current one to generate to proper imports.
- */
- function getIncludes(sourceCode) {
- var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
- var match = regex.exec(sourceCode);
- var includes = new Set();
- while (match != null) {
- let includeFile = match[1];
- // Uniform declaration
- if (includeFile.indexOf("__decl__") !== -1) {
- includeFile = includeFile.replace(/__decl__/, "");
- // Add non UBO import
- const noUBOFile = includeFile + "Declaration";
- includes.add(noUBOFile);
- includeFile = includeFile.replace(/Vertex/, "Ubo");
- includeFile = includeFile.replace(/Fragment/, "Ubo");
- const uBOFile = includeFile + "Declaration";
- includes.add(uBOFile);
- }
- else {
- includes.add(includeFile);
- }
- match = regex.exec(sourceCode);
- }
- return includes;
- }
- /**
- * Generate a ts file per shader file.
- */
- function main(isCore) {
- return through.obj(function (file, enc, cb) {
- if (file.isNull()) {
- cb(null, file);
- return;
- }
- if (file.isStream()) {
- cb(new PluginError("Process Shader", "Streaming not supported."));
- }
-
- const filename = path.basename(file.path);
- const normalized = path.normalize(file.path);
- const directory = path.dirname(normalized);
- const shaderName = getShaderName(filename);
- const tsFilename = filename.replace('.fx', '.ts');
- let fxData = file.contents.toString();
- // Remove Trailing whitespace...
- fxData = fxData.replace(/[^\S\r\n]+$/gm, "");
- // Generate imports for includes.
- let includeText = "";
- const includes = getIncludes(fxData);
- includes.forEach((entry) => {
- if (isCore) {
- includeText = includeText + `import "./ShadersInclude/${entry}";
- `;
- }
- else {
- includeText = includeText + `import "babylonjs/Shaders/ShadersInclude/${entry}";
- `;
- }
- });
- // Chose shader store.
- const isInclude = directory.indexOf("ShadersInclude") > -1;
- const shaderStore = isInclude ? "IncludesShadersStore" : "ShadersStore";
- let effectLocation;
- if (isCore) {
- if (isInclude) {
- effectLocation = "../../Materials/effect";
- includeText = includeText.replace(/ShadersInclude\//g, "");
- }
- else {
- effectLocation = "../Materials/effect";
- }
- }
- else {
- effectLocation = "babylonjs/Materials/effect";
- }
- // Fill template in.
- let tsContent = tsShaderTemplate.replace('##EFFECTLOCATION_PLACEHOLDER##', effectLocation);
- tsContent = tsContent.replace('##INCLUDES_PLACEHOLDER##', includeText);
- tsContent = tsContent.replace('##NAME_PLACEHOLDER##', shaderName);
- tsContent = tsContent.replace('##SHADER_PLACEHOLDER##', fxData);
- tsContent = tsContent.replace('##SHADERSTORE_PLACEHOLDER##', shaderStore);
- tsContent = tsContent.replace('##EXPORT_PLACEHOLDER##', `/** @hidden */
- export var ${shaderName} = { name, shader };`)
- // Go to disk.
- fs.writeFileSync(directory + '/' + tsFilename, tsContent);
- return cb();
- });
- }
- module.exports = main;
|