laurentlb / shader-minifier

Minify and obfuscate GLSL or HLSL code

Home Page:https://ctrl-alt-test.fr/minifier/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

I really liked this project, but struggling to use in a bundler

VanderSP opened this issue · comments

Hi! I was searching for something nice to obfuscate optimize my shaders in bundle, then this project is the only one that´s clever!

I losing entire day trying to make a plugin with gpt help, it´s a mess... i ran the cli, read the glsl in text way (because js looked like non es6 but, maybe using some fileloader?), then i read the glsl minified in text, inject in a js template, spit out, erase temp glsl... and even this way, i would not know how to watch glsl files being changed, i always work in build watch mode... also i tried to hook in on beforeCompile so i can import the result... im quite tired and lost, so im writing for you save me!

thanks in advance

i got it working direclty from glsl, when i used preserve externals, i think only think i need now, is glsl trigger watch

because js looked like non es6

What's the issue? Did get an error when using the JS output?

the js contains some vars, but theres no exports, so i thought u made it for use require instead import... but i think if i have a es6 js output all would work fine, like watch

What change would you need in the file?

If you replace var with export const, it works?

well, it works, but this would require you changing stuff, and still i would ran in the issue i can´t watch the glsl source files...

const { execSync } = require('child_process')
const fs = require('fs')
const path = require('path')

class ShaderMinifierPlugin {
  constructor(options) {
    this.options = options || {}
    this.initialRun = true
  }

  apply(compiler) {
    compiler.hooks.beforeCompile.tap('ShaderMinifierPlugin', () => {
      // Skip if it's not the initial run or if it's not a production build
      if (!this.initialRun || process.env.NODE_ENV !== 'production') {
        return
      }

      const shaderDirectories = [
        path.resolve(__dirname, 'src', 'View', 'Shaders', 'Transitions')
      ]
      const outputDir = path.resolve(__dirname, 'src', 'View', 'Shaders', 'Minified', 'Transitions')
      const shaderExtensions = ['.glsl']
      const outputExtension = '.js'  // Assuming the minifier outputs .js files

      this.initialRun = false

      // Ensure the output directory exists
      if (!fs.existsSync(outputDir)) {
        fs.mkdirSync(outputDir, { recursive: true })
      }

      shaderDirectories.forEach(shaderDir => {
        const shaderFiles = fs.readdirSync(shaderDir).filter(file => {
          return shaderExtensions.includes(path.extname(file))
        })

        shaderFiles.forEach(file => {
          const inputFilePath = path.join(shaderDir, file)
          const outputFileName = path.basename(file, path.extname(file)) + outputExtension
          const outputFilePath = path.join(outputDir, outputFileName)
          try {
            execSync(`shader_minifier.exe --format js --preserve-externals ${inputFilePath} -o ${outputFilePath}`)
            console.log(`Successfully minified shader: ${file} to ${outputFileName}`)
          } catch (error) {
            console.error(`Error minifying shader: ${inputFilePath}`, error)
          }
        })
      })
    })
  }
}

module.exports = ShaderMinifierPlugin

Changing the output of Shader Minifier is a valid feature request. We can output something compatible with ES6 modules.

However, watching the files is the job of your build tool. I would encourage you to check with them (or on stackoverflow) if you need help with it.

Thanks for fast replies! i can import glsl via rawloader, but obviously es6 would be nice... also if possible omit _glsl at the end of names... but yes i must find a way to watch .glsl source files that feed the minifier... i found very frustrating to maybe need to use chokidar... im not deep bundler genius lol

Hey I`ve just got the best idea, can you please make it accept .js as input? like following same pattern of output:

Input is js with some export const glsl =

but about output, i can deal with glsl output, because via rawloader i can read it, so keeping glsl at output it will prevent a retrigger from bundler (BUT I CAN BE WRONG HERE) because i think the plugin hooking at beforeCompile would prevent that naturally (also enabling importing the recent minified file).

Thanks!

No, sorry. We can accept only shader files as input.

I think the best solution for me is still using raw loader with glsl file output, in text mode... just figure out how to watch glsl changes

with help of gpts, i created a big build script that does everything detailed in a way that works,

exec(shader_minifier.exe --format text --no-renaming --aggressive-inlining --preprocess ${inputFilePath} -o ${outputFilePath}, (error, stdout, stderr) => {

in simple shaders, i noted that --preserve-externals (maybe unform names?) is enough... but opted to norenaming, because in complex shader i dunno why breaked (tested preserve globals also same thing)...

enabled aggressive inlining but dont noted much agressiveness (i dont understand fully the concept maybe)
enabled preprocess because sounds good, but dont know when it´s triggered :D

Thanks! (at least now no sniffers in the bundle!)