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///
, unlesscompress
option is set totrue
. -
Starting from
v1.2.0
this plugin is fully compatible withvite^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 withvite^4.0.0
. -
Starting from
v0.5.4
this plugin supports customcompress
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 whenwatch
option is set totrue
. -
Starting from
v0.4.0
this plugin supports chunk imports from project root androot
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 yourpackage.json
or consult this issue for possible workarounds. -
Starting from
v0.2.2
this plugin supportscompress
option to optimize output shader length. You might consider setting this totrue
in production environment. -
Starting from
v0.2.0
this plugin uses a config object as a single argument toglsl
function and allows to disable import warnings with thewarnDuplicatedImports
param set tofalse
. -
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 thesourcemap
option is set totrue
. -
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)
);
}