Import, inline (and compress) GLSL shader files
Inspired by threejs-glsl-loader and vite-plugin-string, compatible with Babylon.js, three.js and lygia.
npm i vite-plugin-glsl --save-dev
# or
yarn add vite-plugin-glsl --dev
# or
pnpm add -D vite-plugin-glsl
# or
bun add vite-plugin-glsl --dev
// vite.config.js
import glsl from 'vite-plugin-glsl';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [glsl()]
});
Add extension declarations to your types
in tsconfig.json
:
{
"compilerOptions": {
"types": [
"vite-plugin-glsl/ext"
]
}
}
or as a package dependency directive to your global types:
/// <reference types="vite-plugin-glsl/ext" />
glsl({
include: [ // Glob pattern, or array of glob patterns to import
'**/*.glsl', '**/*.wgsl',
'**/*.vert', '**/*.frag',
'**/*.vs', '**/*.fs'
],
exclude: undefined, // Glob pattern, or array of glob patterns to ignore
warnDuplicatedImports: true, // Warn if the same chunk was imported multiple times
defaultExtension: 'glsl', // Shader suffix when no extension is specified
compress: false, // Compress output shader code
watch: true, // Recompile shader on change
root: '/' // Directory for root imports
})
root
├── src/
│ ├── glsl/
│ │ ├── chunk0.frag
│ │ ├── chunk3.frag
│ │ ├── main.frag
│ │ ├── main.vert
│ │ └── utils/
│ │ ├── chunk1.glsl
│ │ └── chunk2.frag
│ └── main.js
├── vite.config.js
└── package.json
// main.js
import fragment from './glsl/main.frag';
// main.frag
#version 300 es
#ifndef GL_FRAGMENT_PRECISION_HIGH
precision mediump float;
#else
precision highp float;
#endif
out vec4 fragColor;
#include chunk0.frag;
void main (void) {
fragColor = chunkFn();
}
// chunk0.frag
// ".glsl" extension will be added automatically:
#include utils/chunk1;
vec4 chunkFn () {
return vec4(chunkRGB(), 1.0);
}
// utils/chunk1.glsl
#include chunk2.frag;
#include ../chunk3.frag;
vec3 chunkRGB () {
return vec3(chunkRed(), chunkGreen(), 0.0);
}
// utils/chunk2.frag
float chunkRed () {
return 0.0;
}
// chunk3.frag
float chunkGreen () {
return 0.8;
}
Will result in:
// main.frag
#version 300 es
#ifndef GL_FRAGMENT_PRECISION_HIGH
precision mediump float;
#else
precision highp float;
#endif
out vec4 fragColor;
float chunkRed () {
return 0.0;
}
float chunkGreen () {
return 0.8;
}
vec3 chunkRGB () {
return vec3(chunkRed(), chunkGreen(), 0.0);
}
vec4 chunkFn () {
return vec4(chunkRGB(), 1.0);
}
void main (void) {
fragColor = chunkFn();
}
Starting from v1.3.0
this plugin will not remove comments starting with ///
, unless compress
option is set to true
.
Starting from v1.2.0
this plugin is fully compatible with vite^5.0.0
.
Starting from v1.1.1
this plugin has a complete TypeScript support. Check "Usage" > "With TypeScript" for more info.
Starting from v1.0.0
this plugin is fully compatible with vite^4.0.0
.
Starting from v0.5.4
this plugin supports custom compress
callback function to optimize output shader length after all shader chunks have been included.
Starting from v0.5.0
this plugin supports shaders hot reloading when watch
option is set to true
.
Starting from v0.4.0
this plugin supports chunk imports from project root and root
option to override the default root directory.
Starting from v0.3.0
this plugin is pure ESM. Consider updating your project to an ESM module by adding "type": "module"
in your package.json
or consult this issue for possible workarounds.
Starting from v0.2.2
this plugin supports compress
option to optimize output shader length. You might consider setting this to true
in production environment.
Starting from v0.2.0
this plugin uses a config object as a single argument to glsl
function and allows to disable import warnings with the warnDuplicatedImports
param set to false
.
Starting from v0.1.5
this plugin warns about duplicated chunks imports and throws an error when a recursive loop occurres.
Starting from v0.1.2
this plugin generates sourcemaps using vite esbuild when the sourcemap
option is set to true
.
Starting from v0.1.0
this plugin supports WebGPU shaders with .wgsl
extension.
Starting from v0.0.9
this plugin supports optional semicolons at the end of #include
statements.
Starting from v0.0.7
this plugin supports optional single and double quotation marks around file names.
When used with three.js r0.99 and higher, it's possible to include shader chunks as specified in the documentation, those imports will be ignored by vite-plugin-glsl
since they are handled internally by the library itself:
#include <common>
vec3 randVec3 (const in vec2 uv) {
return vec3(
rand(uv * 0.1), rand(uv * 2.5), rand(uv)
);
}