UstymUkhman / vite-plugin-glsl

:spider_web: Import, inline (and compress) GLSL shader files :electric_plug:
https://www.npmjs.com/package/vite-plugin-glsl
MIT License
321 stars 21 forks source link

Could it support custom decompression ? #47

Closed uctakeoff closed 1 year ago

uctakeoff commented 1 year ago

The custom compress option is a very good idea.

I came up with an idea to take advantage of this. The way I would use a compression library like lz-string to literally "compress" the file.

const compressShader = (shader: string) => {
  const s = shader.replace(...);
  return LZString.compressToUTF16(s);
}

This method worked well. By decoding before compileShader() on the read side, it worked as expected.

import vs from '../glsl/shader.vert';
const vsd = LZString.decompressFromUTF16(vs);

But if possible, a decompress callback option would be a smarter implementation. I would be glad if you could support this.

UstymUkhman commented 1 year ago

Hi @uctakeoff and thanks for using this plugin!

I'm not 100% sure I'm understanding your request though. Currently a custom compress callback can be used at build time (it makes more sense in production environments, but it's totally valid in development as well) to save some space and it will output a compressed shader when importing it in a .js file.

It is possible to add a custom decompress callback, but I need your help to figure out a use case for this: I guess it won't make sense decompressing it before passing to JS 'cause it will mean - compress a shader and immediately after decompress it so it will have the original shape when importing into .js file..?

Or the logic behind that is to allow using already compressed shaders before even parsing them via vite-plugin-glsl so you can import them decompressed into JavaScript..?

Both options are possible, I just cannot quite understand the purpose of having such functionality.

If on the other hand, you want to call a custom decompress function (originally passed as an option to this plugin) right from a .js file, even though this also might be possible if I save it in some "static" method in order to expose it later, you will need to import this plugin at least twice: once in your vite.config file and then again in a .js file that will call this decompress callback.

Honestly sounds weird to me 'cause I thought vite plugins should be used only in a vite.config file.

uctakeoff commented 1 year ago

Perhaps I have misunderstood the usage.

I thought glsl's compression feature was to reduce the package size after build. (This is what is called "minify".) The smaller the package size, the better. If this is the case, I thought that the compressed code does not necessarily have to be readable. You can use gzip if it is effective in compression.

Also, for some products, it makes sense to make the source code less readable. It has the effect of making it difficult for others to reverse engineer the code. (Of course, it is not perfect.)

For such applications, I thought it would make sense to use a compression algorithm or encryption process in the glsl plugin's compression function.

When I thought of such a device, I thought it would be nice to have a decompression function. Am I misinterpreting something?

UstymUkhman commented 1 year ago

Yeah, I think we've misunderstood each other. 😅

I thought glsl's compression feature was to reduce the package size after build.

vite-plugin-glsl's compression is actually a minifier which might use a default algorithm (with compress: true) or a custom callback passed to the same compress option. What it's aimed to do at the and of the day, is to strip away whitespaces from your shaders in order to reduce bundle size and load them a bit faster.

For such applications, I thought it would make sense to use a compression algorithm or encryption process in the glsl plugin's compression function.

Yeah, I agree, but I think at that point it would make more sense apply the same compression algorithm to the whole bundle and not only to your shaders. At the end of the day, those are just strings in your .js files.

I've found these compression plugins that might do just what you need, but I'm not sure about decompression. Maybe that could be something to develop from scratch...

Hope this helps, cheers!

uctakeoff commented 1 year ago

Unfortunately, the plug-ins you mentioned do not seem to have any obfuscation effect. The general compress/minify algorithm does not allow modification of the string content without permission. In short, I was hoping for the effect that the string would not look glsl at first glance.

It would have been nice to have decompress: boolean|((s: string) => string) as well as the compress option.

Thank you for your consideration.

UstymUkhman commented 1 year ago

In short, I was hoping for the effect that the string would not look glsl at first glance.

Got it. Yeah, unfortunately that's out of scope of this plugin too. No problem, thanks for using it. Please consider smashing a star button if you've found it any useful, thanks!