Skip to content

UstymUkhman/vite-plugin-glsl

Repository files navigation

Vite Plugin GLSL

Import, inline (and compress) GLSL shader files

npm GitHub package.json version GitHub

Inspired by threejs-glsl-loader and vite-plugin-string, compatible with Babylon.js, three.js and lygia.

Installation

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

Usage

// vite.config.js
import glsl from 'vite-plugin-glsl';
import { defineConfig } from 'vite';

export default defineConfig({
  plugins: [glsl()]
});

With TypeScript

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" />

Default Options

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
})

Example

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();
}

Change Log

  • 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.

Note:

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)
  );
}