gulp-processShaders.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104
  1. var through = require('through2');
  2. var PluginError = require('gulp-util').PluginError;
  3. let path = require('path');
  4. let fs = require('fs');
  5. let tsShaderTemplate =
  6. `import { Effect } from "babylonjs";
  7. ##INCLUDES_PLACEHOLDER##
  8. let name = '##NAME_PLACEHOLDER##';
  9. let shader = \`##SHADER_PLACEHOLDER##\`;
  10. Effect.##SHADERSTORE_PLACEHOLDER##[name] = shader;
  11. export { shader, name };
  12. `;
  13. function getShaderName(filename) {
  14. let parts = filename.split('.');
  15. if (parts[1] !== 'fx') {
  16. return parts[0] + (parts[1] === 'fragment' ? 'Pixel' : 'Vertex') + "Shader";
  17. } else {
  18. return parts[0];
  19. }
  20. }
  21. function getIncludes(sourceCode) {
  22. var regex = /#include<(.+)>(\((.*)\))*(\[(.*)\])*/g;
  23. var match = regex.exec(sourceCode);
  24. var includes = new Set();
  25. while (match != null) {
  26. let includeFile = match[1];
  27. // Uniform declaration
  28. if (includeFile.indexOf("__decl__") !== -1) {
  29. includeFile = includeFile.replace(/__decl__/, "");
  30. // Add non UBO import
  31. const noUBOFile = includeFile + "Declaration";
  32. includes.add(noUBOFile);
  33. includeFile = includeFile.replace(/Vertex/, "Ubo");
  34. includeFile = includeFile.replace(/Fragment/, "Ubo");
  35. const uBOFile = includeFile + "Declaration";
  36. includes.add(uBOFile);
  37. }
  38. else {
  39. includes.add(includeFile);
  40. }
  41. match = regex.exec(sourceCode);
  42. }
  43. return includes;
  44. }
  45. function main(isCore) {
  46. return through.obj(function (file, enc, cb) {
  47. if (file.isNull()) {
  48. cb(null, file);
  49. return;
  50. }
  51. if (file.isStream()) {
  52. cb(new PluginError("Process Shader", "Streaming not supported."));
  53. }
  54. const filename = path.basename(file.path);
  55. const normalized = path.normalize(file.path);
  56. const directory = path.dirname(normalized);
  57. const shaderName = getShaderName(filename);
  58. const tsFilename = filename.replace('.fx', '.ts');
  59. let fxData = file.contents.toString();
  60. // Trailing whitespace...
  61. fxData = fxData.replace(/[^\S\r\n]+$/gm, "");
  62. let includeText = "";
  63. const includes = getIncludes(fxData);
  64. includes.forEach((entry) => {
  65. if (isCore) {
  66. includeText = includeText + `import "./ShadersInclude/${entry}";
  67. `;
  68. }
  69. else {
  70. includeText = includeText + `import "babylonjs/Shaders/ShadersInclude/${entry}";
  71. `;
  72. }
  73. });
  74. const shaderStore = directory.indexOf("ShadersInclude") > -1 ? "IncludesShadersStore" : "ShadersStore";
  75. let tsContent = tsShaderTemplate.replace('##INCLUDES_PLACEHOLDER##', includeText);
  76. tsContent = tsContent.replace('##NAME_PLACEHOLDER##', shaderName);
  77. tsContent = tsContent.replace('##SHADER_PLACEHOLDER##', fxData);
  78. tsContent = tsContent.replace('##SHADERSTORE_PLACEHOLDER##', shaderStore);
  79. fs.writeFileSync(directory + '/' + tsFilename, tsContent);
  80. return cb();
  81. });
  82. }
  83. module.exports = main;