Giter Club home page Giter Club logo

vite-plugin-glsl's Introduction

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

vite-plugin-glsl's People

Contributors

abernier avatar alvinometric avatar brunoimbrizi avatar codyjasonbennett avatar quarksb avatar ustymukhman avatar yunyoujun avatar ztolley avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

vite-plugin-glsl's Issues

Require RSM Error: Must use import to load ES Module

Environment

MacOS: 12.6
Node: 14.18.1
Vite: ^3.0.9

Steps to reproduce

  • Follow plugin installation guidelines
  • Run npm run dev

Expected result
vite-plugin-glsl is imported & added to vite config

Actual result
Import error:

failed to load config from /Users/michael/Sites/photoalbum/vite.config.js
error when starting dev server:
Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: /Users/michael/Sites/photoalbum/node_modules/vite-plugin-glsl/src/index.js
require() of ES modules is not supported.
require() of /Users/michael/Sites/photoalbum/node_modules/vite-plugin-glsl/src/index.js from /Users/michael/Sites/photoalbum/vite.config.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules.
Instead rename index.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/michael/Sites/photoalbum/node_modules/vite-plugin-glsl/package.json.

Additional information
See my vite.config.js below:

import vue from '@vitejs/plugin-vue'
import vueJsx from '@vitejs/plugin-vue-jsx'
import { fileURLToPath, URL } from 'node:url'
import { defineConfig } from 'vite'
import { glsl } from 'vite-plugin-glsl'
import StylelintPlugin from 'vite-plugin-stylelint'
export default defineConfig({
  lintOnSave: true,
  css: {
    preprocessorOptions: {
      scss: {
        additionalData: `
          @use "@/assets/scss/utils/breakpoints.scss" as *;
          @use "@/assets/scss/_mixins.scss" as *;
          @use "@/assets/scss/utils/reset.scss" as *;
          @use "@/assets/scss/_variables.scss" as *;
        `,
      },
    },
  },
  plugins: [
    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: '/',
    }),
    vue(),
    vueJsx(),
    StylelintPlugin({
      fix: true,
      quite: true,
    }),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url)),
    },
  },
  server: {
    port: 3000,
  },
})

дуже дякую!

how can i remove comments like // or /* */

hi guys, i have set compress to true in my vite.config.ts,
but when i build the project, comments are still here; Eg:

uniform float uRange; // \u5C55\u793A\u533A\u95F4\r
uniform float uTotal; // \u7C92\u5B50\u603B\u6570\r
uniform vec3 uColor; //fs\u91CC\u4F1A\u7528\u5230\r
`,dt=`/**\r
 * \u98DE\u7EBF\u7247\u5143\u7740\u8272\u5668\r
 * @remark \u8BE5\u7740\u8272\u5668\u9700\u8981\u4E00\u4E2Auniform\uFF0C\r
 *         u_color\u81EA\u5B9A\u4E49\u989C\u8272\r
 */

something else i need to do?
thanks for ur help!

Error while importing shader

i wanted to make a shaders using dependencies

#pragma glslify: noise = require(glsl-noise/simplex/2d)

void main() {
  float brightness = noise(gl_FragCoord.xy);

  gl_FragColor = vec4(vec3(brightness), 1.);
}

I did install the noise required by npm

and got in browser console :

webgl-utils.js:66 *** Error compiling shader '[object WebGLShader]':WARNING: 0:1: 'glslify' : unrecognized pragma
ERROR: 0:4: '' : No precision specified for (float)
ERROR: 0:4: 'noise' : no matching overloaded function found
�
1: #pragma glslify: noise = require(glsl-noise/simplex/2d)
2: 
3: void main() {
4:   float brightness = noise(gl_FragCoord.xy);
5: 
6:   gl_FragColor = vec4(vec3(brightness), 1.);
7: }

It seems it did not compile the shader

`#version 300 es` comment gets removed

With WebGL 2 some GLSL features require the #version 300 es comment to be present. Unfortunately vite-plugin-glsl removes this comment just as a regular comment.

Watch, hot reload, server restart on 1.1.0

I noticed some issues on version 1.1.0 and I also have a few questions:

  1. Is config() still needed?
  2. Passing watch = false on initialisation now has no effect.
  3. Is it necessary to call server.restart() in handleHotUpdate()?
    Restarting the server makes every reload much slower. A quick test removing that call (or removing handleHotUpdate altogether) resulted in much faster reloads. It seems that Vite already understands the project needs to be rebuilt without having to force restart the server.

Recursion Detection Warning fires when there is no recursion.

If you have two separate WebGL programs on you're site, and say programA.frag and programB.frag both include a utility function, the "Recursion detected" warning fires. Obviously, recursion would never be the first problem you would run into when trying to macro two separate shader programs together.

Checking to see if a file is included more than once is sufficient for this specific scenario, but it should be taken into account that their can be completely separate include trees.

Warning: 'programB.frag' was included multiple times.
Please avoid multiple imports of the same chunk in order to avoid unwanted recursions. Last import found in file 'noise.glsl'.

Nothing breaks, but it is annoying for those that like a clean console window. Other than that, thanks for providing this tool! It works way better than any webpack solution I've used.

A question about quotes around nested include file names

Hi! Thanks for creating this plugin - it was just what I needed. Well, almost, which is why I'm creating this issue.

I was recently building a WegGL application using vite and needed this exact functionality, but when I attempted to use this plugin it was unable to process nested includes from other GLSL files if they used quotes around the filename. Specifically, I was using Lygia, but I think that #include "filename" is expected to work more generally (?). So, I edited your library to support optional quotation marks around file names and that seems to have done the trick.

As a result, I wanted to see:

  • If it was a conscious design decision to not handle quotes around file names. From what I can see in other libraries, this seems expected (see here, for example).
  • If not, would you be interested in a PR that adds that functionality?

Thanks!

Does it support the react WGSL apps build with vite?

My Project Link: web-graphics
Frameworks: Vite, React, swc, WGSL
The Error Message:

> yarn dev
Error: The following dependencies are imported but could not be resolved:

  shaders/triangle.wgsl
...


> yarn build
[vite]: Rollup failed to resolve import "shaders/triangle.wgsl" from "C:/Users/z2832/Project/web-graphics/src/App.tsx".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`build.rollupOptions.external`
...

Changes to #included shaders not taking effect, unless parent shader is changed or vite is restarted

Reproducible here:
https://stackblitz.com/edit/vitejs-vite-hwdvnu?file=included.glsl

  1. Change something in index.glsl
    → changes take effect, refresh happens
  2. Change something in included.glsl
    → changes don't take effect, nothing happens, even a manual refresh doesn't help
  3. Change something in index.glsl, or restart vite
    → changes to included.glsl take effect

This sounds like it could be related to #12?

P.S. Thank you for building this plugin! It's been a great help for wrangling shaders in my game projects. :)

I facing an issue while using a package which uses .glsl files (sheryjs)

when after using glsl plugin in the vite.config.js. I am still getting this error

No loader is configured for ".glsl" files: node_modules/sheryjs/src/shaders/effect4/vertex.glsl

node_modules/sheryjs/src/Effects.js:9:21:
  9 │ import vertex_4 from './shaders/effect4/vertex.glsl'

No loader is configured for ".glsl" files: node_modules/sheryjs/src/shaders/effect2/vertex.glsl

node_modules/sheryjs/src/Effects.js:5:21:
  5 │ import vertex_2 from './shaders/effect2/vertex.glsl'

vite.config.ts

import { defineConfig } from "vite";
import glsl from "vite-plugin-glsl";
import react from "@vitejs/plugin-react-swc";
import path from "path";
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react(), glsl()],

resolve: {
    alias: {
        "@": path.resolve(__dirname, "./src"),
    },
},

});

package.json

import { defineConfig } from "vite";
import glsl from "vite-plugin-glsl";
import react from "@vitejs/plugin-react-swc";
import path from "path";

export default defineConfig({
plugins: [react(), glsl()],

resolve: {
    alias: {
        "@": path.resolve(__dirname, "./src"),
    },
},

});

can you please assist me in this.

glslify support

Hello fellow tech enthusiast,

Does this plugin also support glslify to compile glslify shader code?
I get this error in my browser:

three.module.js:18758 THREE.WebGLProgram: Shader Error 0 - VALIDATE_STATUS false

Program Info Log: invalid shaders�
VERTEX

WARNING: 0:73: 'glslify' : unrecognized pragma
WARNING: 0:74: 'glslify' : unrecognized pragma
WARNING: 0:75: 'glslify' : unrecognized pragma

Have a great day!

Error "require() of ES Module not supported." after adding vite-plugin-glsl to vite.config.ts

Hi, thanks for working on this!

Unfortunately, i stumble right at the beginning when trying to make this work.

If I add vite-plugin-glsl to my config like advised ...

import { fileURLToPath, URL } from 'node:url'

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import glsl from 'vite-plugin-glsl';


// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    glsl(), 
    vue(),
  ],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    }
  }
})

... I get this error:

failed to load config from .../project/vite.config.ts
error when starting dev server:
Error [ERR_REQUIRE_ESM]: require() of ES Module .../project/node_modules/vite-plugin-glsl/src/index.js from .../project/vite.config.ts not supported.
Instead change the require of index.js in .../project/vite.config.ts to a dynamic import() which is available in all CommonJS modules.
    at Object._require.extensions.<computed> [as .js] (file://.../project/node_modules/vite/dist/node/chunks/dep-5605cfa4.js:63157:17)
    at Object.<anonymous> (.../project/vite.config.ts:35:39)
    at Object._require.extensions.<computed> [as .js] (file://.../project/node_modules/vite/dist/node/chunks/dep-5605cfa4.js:63154:24)
    at loadConfigFromBundledFile (file://.../project/node_modules/vite/dist/node/chunks/dep-5605cfa4.js:63162:21)
    at loadConfigFromFile (file://.../project/node_modules/vite/dist/node/chunks/dep-5605cfa4.js:63020:34)
    at async resolveConfig (file://.../project/node_modules/vite/dist/node/chunks/dep-5605cfa4.js:62643:28)
    at async createServer (file://.../project/node_modules/vite/dist/node/chunks/dep-5605cfa4.js:61943:20)
    at async CAC.<anonymous> (file://.../project/node_modules/vite/dist/node/cli.js:707:24)

Compress erros on Three with chunks and imports

First of all, great plugin, thanks for that.
I tried to use the compress: true prop to compress my shader but somehow it breaks the code.
My files includes both import and a lot of threejs chuks (aka <#include... >)

Any clue?
I'm on "vite-plugin-glsl": "^1.1.2" and "three": "^0.157.0"

EDIT: in the docs you stated "Starting from v0.5.4 this plugin supports custom compress callback function to optimize output shader length after all shader chunks have been included." so it might solve my issue but I have no clue on what I need to do there since docs are not explain that :)

image

Hot Reload Not Firing on Included Shaders

Hey its me again! Not a bug, but an important missing feature. A change to an included shader doesn't update the including shader, therefore never firing hot reload.

I don't know much about plugin development, but hopefully thats possible. The best solution would be the included shaders keep track of their parent and you work the changes downward. Hopefully thats possible, I'd assume it is.

Would you like me to fork and pull request? I'm writing a pretty large web game/game engine so good GLSL support is vital to me. I can add minification (if it doesn't exist), the recursive hot reloading, and the multi-shader support. This is your project though, if you're able to get those features added soon and are looking forward to adding them I can stay out of your way. When can you get these features added by?

Seeking Help: Manual Refresh Required for GLSL Code Updates in Vite/React-Three-Fiber

Hey there! First off thank you for taking the time to write this plugin and share it!

I am having troubling getting Hot Module Reloading to work when editing glsl code in my Vite / React-Three-Fiber setup. I can get everything to compile and render just fine, but in order to see any updates to my shader I have the manually refresh the browser each time, which is annoying. In my hunt for a solution I came across your plugin, but despite installing it and getting things running I'm still having to manually refresh the page each time I make a change to glsl whether it's inline JS as a string or in a separate .glsl file.

Here's a github repo with my setup: https://github.com/klufkin/r3f-vite-shaders-test
I am using node.js v16.9.1 and npm v7.21.1 locally.

Any ideas as to what may be the issue would be greatly appreciated! Thank you!

Unable to import vite module

Hey,
Thank you for making this vite plugins to better manage file imports. However, I need your help as I can't seem to get working, even after following the README.md and ensuring that the npm packages was saved as a dev dependency.

I am currently getting the following error related to this plugin regardless of vite dev/build.

failed to load config from /home/henri/Documents/aviaryTech/viteExperiment/vite.config.js
error when starting dev server:
TypeError: glsl is not a function
    at file:///home/henri/Documents/aviaryTech/viteExperiment/vite.config.js?t=1633044514306:9:5
    at ModuleJob.run (internal/modules/esm/module_job.js:169:25)
    at async Loader.import (internal/modules/esm/loader.js:177:24)
    at async loadConfigFromFile (/home/henri/Documents/aviaryTech/viteExperiment/node_modules/vite/dist/node/chunks/dep-972722fa.js:75828:31)
    at async resolveConfig (/home/henri/Documents/aviaryTech/viteExperiment/node_modules/vite/dist/node/chunks/dep-972722fa.js:75434:28)
    at async createServer (/home/henri/Documents/aviaryTech/viteExperiment/node_modules/vite/dist/node/chunks/dep-972722fa.js:73957:20)
    at async CAC.<anonymous> (/home/henri/Documents/aviaryTech/viteExperiment/node_modules/vite/dist/node/cli.js:13963:24)

The current vite.config.js implementation is simple for now:

import { defineConfig } from 'vite'
import { svelte } from '@sveltejs/vite-plugin-svelte'
//import vitePluginString from 'vite-plugin-string'
import glsl from 'vite-plugin-glsl';
// https://vitejs.dev/config/
export default defineConfig({
  plugins:
    [svelte(),
    glsl()],
  optimizeDeps: {
    exclude: ["svelte-navigator"],
  }
})

Any help is greatly appreciated,
@dikbek, pinging you for tracking

Tips for making this work with GLSL Lint

I have found that you can make this work with https://marketplace.visualstudio.com/items?itemName=dtoplak.vscode-glsllint

Just use the following script replacing the script_to_run to path to glslangValidator. Only downside is that all errors are printed 2 lines below.

#!/bin/bash

# The script you want to forward the arguments to
script_to_run="/opt/homebrew/bin/glslangValidator"

# Generate a filename based on the current timestamp
timestamp=$(date +%Y%m%d%H%M%S)
log_file="/tmp/glslangValidator_log.txt"

# Log the input arguments
echo "[$timestamp] Input arguments: $@" > "$log_file"

# Concatenate the specified lines to the standard input
echo -e "#version 100\n#extension GL_GOOGLE_include_directive : require\n$(cat)" | "$script_to_run" "$@" 

HMR in vuejs working weirdly

It seems vite-plugin-glsl hmr doesnt work straight forward in vite + vuejs + threejs.

I code a simple demo of how i make it works but some points seems weird to me :

  • I have to create another js file to handle correctly the hot reloading
  • I have to handle manually the hotreloading of the material using a watch from vue

Does it seems correct to you guys or do you have a suggestion to make it more clean ?

If this is the best solution i should probablu write a plugin for vue to make all this automatic?

Main view

<template>
	<div class="ThreeView">
		<div ref="title" class="title">THREEJS</div>
		<div ref="subtitle" class="subtitle">Simple example</div>
	</div>
</template>

<script>
import { Mesh, BoxGeometry, ShaderMaterial, Scene, WebGLRenderer, PerspectiveCamera, Vector3 } from 'three'
import {stage } from '@/makio/core/stage'
import {basicFS} from '@/3d/shaders/shaderLoader'

// import basicFrag from '@/3d/shaders/basic.frag'

export default {
	name: 'ThreeView',
	mounted() {
		this.init()
	},
	methods:{
		init(){
			console.log('init')
			this.renderer = new WebGLRenderer({})
			this.renderer.setPixelRatio(stage.devicePixelRatio)
			this.renderer.setSize(stage.width, stage.height)
			this.renderer.domElement.className = 'three'
			document.body.appendChild(this.renderer.domElement)
			this.scene = new Scene()
			this.camera = new PerspectiveCamera(50, stage.width / stage.height, 0.1, 100)
			this.camera.position.z = 5
			this.camera.updateMatrixWorld(true)
			this.camera.lookAt(new Vector3(0,0,0))
			this.cube = new Mesh(new BoxGeometry(1, 1, 1), new ShaderMaterial({ fragmentShader:basicFS.value }))
			watch(basicFS,(value,oldValue)=>{
				this.cube.material.fragmentShader = value
				this.cube.material.needsUpdate = true
			})
			this.scene.add(this.cube)
			stage.onUpdate.add(this.update)
			this.isInit = true
		},
		update(dt){
			this.renderer.render(this.scene, this.camera)
		}
	},
}
</script>

<style lang="stylus" scoped>
.ThreeView
	color #fff
	display flex
	min-height 100%
	flex-direction column
	justify-content center
	align-items center
	.title
		font-size 3rem
	.subtitle
		font-size 1.5rem
</style>

shaderLoader.js

import { ref } from 'vue';

import basic from './basic.frag';
const basicFS = ref(basic);

if (import.meta.hot) {
  import.meta.hot.accept('./basic.frag', (newModule) => {
    basicFS.value = newModule.default;
  })
}

export {basicFS};

No loader is configured for ".glsl" in node_modules file

After installing and configuring the plugin, I'm able to require .glsl files, as long as they are part of the application. However, when importing a package (installed in node_modules) which also requires a .glsl file I get an esbuild error:

'No loader is configured for ".glsl" files: node_modules/my-package/glsl/vertex.glsl'

I've been looking at Vite options, esbuild options and could not find a solution, yet. Is this behavior expected?

Edit: found this issue vitejs/vite#1873 which seems related, but I don't fully understand the solution.

Failed to resolve entry for package "vite-plugin-glsl" in vanilla TypeScript project.

X [ERROR] [plugin externalize-deps] Failed to resolve entry for package "vite-plugin-glsl". The package may have incorrect main/module/exports specified in its package.json: No known conditions for "." entry in "vite-plugin-glsl" package

The plugin appears to work correctly with a Vite vanilla JavaScript project, but not a vanilla TypeScript project.

Node version: 18.13.0
npm version: 9.3.1
Vite version: 4.0.4

Repro steps:

  1. npm create vite@latest
  2. Chose the default project name, vite-project, and press the Enter key
  3. Select Vanilla and press the Enter key
  4. Select TypeScript and press the Enter key
  5. cd vite-project
  6. npm install
  7. npm install --save-dev vite-plugin-glsl
  8. Create a vite.config.ts file and add the following code:
    import { defineConfig } from "vite";
    import glsl from "vite-plugin-glsl";
    
    export default defineConfig({
            plugins: [ glsl() ]
    });
  9. npm run dev

Result: The project won't build and produces the following error...

X [ERROR] [plugin externalize-deps] Failed 
to resolve entry for package "vite-plugin-glsl". The package may have incorrect main/module/exports specified in its package.json: No known conditions for "." entry in "vite-plugin-glsl" package

    node_modules/esbuild/lib/main.js:1365:27:
      1365 │ ... result = await callback({ 
           ╵                    ^

    at packageEntryFailure (/vite-project/node_modules/vite/dist/node/chunks/dep-5e7f419b.js:21837:11)
    at resolvePackageEntry (/vite-project/node_modules/vite/dist/node/chunks/dep-5e7f419b.js:21832:9)
    at tryNodeResolve (/vite-project/node_modules/vite/dist/node/chunks/dep-5e7f419b.js:21572:20)
    at /vite-project/node_modules/vite/dist/node/chunks/dep-5e7f419b.js:62039:40        
    at requestCallbacks.on-resolve (\vite-project\node_modules\esbuild\lib\main.js:1365:28)     
    at handleRequest (\vite-project\node_modules\esbuild\lib\main.js:727:19)
    at handleIncomingPacket (\vite-project\node_modules\esbuild\lib\main.js:749:7)
    at Socket.readFromStdout (\vite-project\node_modules\esbuild\lib\main.js:677:7)
    at Socket.emit (node:events:513:28)    
    at addChunk (node:internal/streams/readable:324:12)

  This error came from the "onResolve"     
  callback registered here:

    node_modules/esbuild/lib/main.js:1287:20:
      1287 │       let promise = setup({   
           ╵                     ^

    at setup (/vite-project/node_modules/vite/dist/node/chunks/dep-5e7f419b.js:62028:27)    at handlePlugins (\vite-project\node_modules\esbuild\lib\main.js:1287:21)
    at buildOrServeImpl (\vite-project\node_modules\esbuild\lib\main.js:974:5)
    at Object.buildOrServe (\vite-project\node_modules\esbuild\lib\main.js:780:5)
    at \vite-project\node_modules\esbuild\lib\main.js:2132:17
    at new Promise (<anonymous>)
    at Object.build (\vite-project\node_modules\esbuild\lib\main.js:2131:14)
    at build (\vite-project\node_modules\esbuild\lib\main.js:1978:51)
    at bundleConfigFile (/vite-project/node_modules/vite/dist/node/chunks/dep-5e7f419b.js:61992:26)

  The plugin "externalize-deps" was        
  triggered by this import

    vite.config.ts:2:17:
      2 │ ...glsl from "vite-plugin-glsl";~~~~~~~~~~~~~~~~~~  

failed to load config from \vite-project\vite.config.ts
error when starting dev server:
Error: Build failed with 1 error:
node_modules/esbuild/lib/main.js:1365:27: ERROR: [plugin: externalize-deps] Failed to 
resolve entry for package "vite-plugin-glsl". The package may have incorrect main/module/exports specified in its package.json: No known conditions for "." entry in "vite-plugin-glsl" package
    at failureErrorWithLog (\vite-project\node_modules\esbuild\lib\main.js:1604:15)
    at \vite-project\node_modules\esbuild\lib\main.js:1056:28
    at runOnEndCallbacks (\vite-project\node_modules\esbuild\lib\main.js:1476:61)
    at buildResponseToResult (\vite-project\node_modules\esbuild\lib\main.js:1054:7)
    at \vite-project\node_modules\esbuild\lib\main.js:1166:14
    at responseCallbacks.<computed> (\vite-project\node_modules\esbuild\lib\main.js:701:9)      
    at handleIncomingPacket (\vite-project\node_modules\esbuild\lib\main.js:756:9)
    at Socket.readFromStdout (\vite-project\node_modules\esbuild\lib\main.js:677:7)
    at Socket.emit (node:events:513:28)    
    at addChunk (node:internal/streams/readable:324:12)

too restrictive `"engines"`

I think your package.json is a bit too restrictive about engines: I get warnings whereas it seems to work just fine with my version of node/npm.

Maybe you could make it a bit more loose?

npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: '[email protected]',
npm WARN EBADENGINE   required: { node: '>= 18.12.1', npm: '>= 9.2.0' },
npm WARN EBADENGINE   current: { node: 'v16.18.0', npm: '8.19.2' }
npm WARN EBADENGINE }

Unable to import the plugin - missing tslib

I have a simple VanillaJs Vite application running.
Tried to add the glsl plugin but I'm getting the following issue after I run vite using npm:

package.json scripts:

 "scripts": {
    "dev": "vite --host",
    "build": "vite build",
    "serve": "vite preview"
  }

Error:

failed to load config from <PATH_TO_PROJECT>/threejs-test/vite.config.js
error when starting dev server:
Error: Cannot find module 'tslib'

Which seems a bit weird? since ts should be supported on vite without any configurations?
Resorted to use the string loader which doesn't require additional modules

Doesn't seem to process nested #include statements without semicolon

I've been attempting to use this plugin to include files from https://github.com/patriciogonzalezvivo/lygia and it seems that vite-plugin-glsl doesn't process any #include statements in nested files unless they end with a ;

As an example:

// in main.frag

// this works
#include "lygia/draw/circle.glsl";
// in lygia/draw/circle.glsl

// All three of these fail to be processed because they don't end with a semicolon
#include "../sdf/circleSDF.glsl"
#include "fill.glsl"
#include "stroke.glsl"

...

Given that lygia works with most other standard GLSL implementations that support #include, I would assume that the semicolon isn't actually required. Could vite-plugin-glsl be updated to remove the requirement for a semicolon at the end of these statements?

Thank you for your work on this plugin!

Could it support custom decompression ?

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.

can't 'go to definition' to source file

I know this is working for ts by define custom module in ext.d.ts
but if try to 'go to definition' for those modules, it can only redirect to the ext.d.ts, not the source file

Any idea how to redirect to the source file?

'include' : invalid directive name

#include ../func/rand.glsl

when i use this code in a glsl file, run it, f12, chrome show me "'include' : invalid directive name"

what's the problem?
thanks!

compact goes wrong with this code

I have this function, but compact won't play nice:

float scaleLogarithmically(float value, float linMin, float linMax, float logMin, float logMax, float scaleOffset) {
    float x = value;
    float x0 = linMin;
    float x1 = linMax;
    float y0 = logMin + scaleOffset;
    float y1 = logMax + scaleOffset;
    return 
       pow(10.,
            ((x - x0) / (x1 - x0)) * (log10(y1) - log10(y0)) + log10(y0)
        ) - scaleOffset;
}

It converts the return\n pow( sequence into returnpow(.

Cannot find module 'node:path'

Hi I'm using this plugin in a newly created project wit svelte and typescript however I'm getting this error:

failed to load config from D:\Documentos\GitHub\piare\vite.config.ts
error when starting dev server:
Error: Cannot find module 'node:path'
Require stack:
- D:\Documentos\GitHub\piare\node_modules\vite\dist\node-cjs\publicUtils.cjs
- D:\Documentos\GitHub\piare\node_modules\vite\index.cjs
- D:\Documentos\GitHub\piare\node_modules\vite-plugin-glsl\dist\index.js
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:889:15)

Checking if the is anybody that can help me? 👀

🔗 Link of my repo with issues in case someone wants to test

The project is basically what you get when running:

npm create vite@latest

and filling for svelte and typescript

Node version v14.17.5 in a Windows 10 machine.

I did see #13 another issue with similar conditions ( svelte and node v14.17)
however the error is different and already try removing the

"type": "module"

from the packaje json. Also Package.json

"devDependencies": {
    "@sveltejs/vite-plugin-svelte": "^1.0.1",
    "@tsconfig/svelte": "^3.0.0",
    "@types/node": "^18.0.4",
    "svelte": "^3.49.0",
    "svelte-check": "^2.8.0",
    "svelte-preprocess": "^4.10.7",
    "tslib": "^2.4.0",
    "typescript": "^4.6.4",
    "vite": "^3.0.0",
    "vite-plugin-glsl": "^0.2.2"
  }
import { defineConfig } from 'vite'
import glsl from 'vite-plugin-glsl';
import { svelte } from '@sveltejs/vite-plugin-svelte'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [svelte()]
})

event when not adding glsl to the plugin array still show the same issue.

also try to change the tsconfig.json

from

"module": "ESNext",

to

"module": "CommonJS",

but the same issue appears. Sorry for the long text but I tried to provide as much details as possible 😥

Can't load shaders

Hi

I follow the readme, but it throws this error: [vite] Internal server error: shaderChunks.at is not a function

I had to do this workaround on loadShaders.js library file.:

I had to replace:
const caller = shaderChunks.at(-1);
to
const caller = shaderChunks[shaderChunks.length-1]

Have you faced the same error?

Watcher crashes when using the plugin with Astro

I created the issue in the Astro project, but it turned out that it was the problem with the plugin itself.

withastro/astro#5672 (comment)

It's a regression by vite-plugin-glsl here since 25fa19e. It relies on the Vite config file and update the utime to restart the server, it should use server.restart() instead as it's cross compatible for metaframeworks without a Vite config file. Please report upstream instead.

glsl files inside node_modules

I ran into a case I bundled my TypeScript and GLSL files into an npm module, and got it loaded in another project. Then it turned out GLSL files inside the module are not loaded correctly. Was this plugin supposed to be used for files inside node_modules/, or any quick options I could use to fix that?

=>> yarn vite --host=0.0.0.0
yarn run v1.22.19
$ /Users/me/repo/triadica/ts-workflow/node_modules/.bin/vite --host=0.0.0.0

  VITE v3.0.5  ready in 104 ms

  ➜  Local:   http://localhost:5173/
  ➜  Network: http://192.168.31.28:5173/
✘ [ERROR] No loader is configured for ".frag" files: node_modules/triadica/shaders/effect-mix.frag

    node_modules/triadica/src/index.mts:11:26:
      11 │ import effectMixFrag from "../shaders/effect-mix.frag";
         ╵                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".glsl" files: node_modules/triadica/shaders/triadica-colors.glsl

    node_modules/triadica/src/config.mts:37:27:
      37 │ ...t glslColorsCode from "../shaders/triadica-colors.glsl";
         ╵                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".glsl" files: node_modules/triadica/shaders/triadica-perspective.glsl

    node_modules/triadica/src/config.mts:26:32:
      26 │ ...pectiveCode from "../shaders/triadica-perspective.glsl";
         ╵                     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".frag" files: node_modules/triadica/shaders/effect-x.frag

    node_modules/triadica/src/index.mts:9:24:
      9 │ import effectXFrag from "../shaders/effect-x.frag";
        ╵                         ~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".glsl" files: node_modules/triadica/shaders/triadica-rotation.glsl

    node_modules/triadica/src/config.mts:28:29:
      28 │ ...slRotationCode from "../shaders/triadica-rotation.glsl";
         ╵                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".vert" files: node_modules/triadica/shaders/effect-x.vert

    node_modules/triadica/src/index.mts:8:24:
      8 │ import effectXVert from "../shaders/effect-x.vert";
        ╵                         ~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".glsl" files: node_modules/triadica/shaders/triadica-noises.glsl

    node_modules/triadica/src/config.mts:27:27:
      27 │ ...t glslNoisesCode from "../shaders/triadica-noises.glsl";
         ╵                          ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

✘ [ERROR] No loader is configured for ".vert" files: node_modules/triadica/shaders/effect-mix.vert

    node_modules/triadica/src/index.mts:10:26:
      10 │ import effectMixVert from "../shaders/effect-mix.vert";
         ╵                           ~~~~~~~~~~~~~~~~~~~~~~~~~~~~

12:28:25 PM [vite] error while updating dependencies:
Error: Build failed with 8 errors:
node_modules/triadica/src/config.mts:26:32: ERROR: No loader is configured for ".glsl" files: node_modules/triadica/shaders/triadica-perspective.glsl
node_modules/triadica/src/config.mts:27:27: ERROR: No loader is configured for ".glsl" files: node_modules/triadica/shaders/triadica-noises.glsl
node_modules/triadica/src/config.mts:28:29: ERROR: No loader is configured for ".glsl" files: node_modules/triadica/shaders/triadica-rotation.glsl
node_modules/triadica/src/config.mts:37:27: ERROR: No loader is configured for ".glsl" files: node_modules/triadica/shaders/triadica-colors.glsl
node_modules/triadica/src/index.mts:8:24: ERROR: No loader is configured for ".vert" files: node_modules/triadica/shaders/effect-x.vert
..
    at failureErrorWithLog (/Users/me/repo/triadica/ts-workflow/node_modules/esbuild/lib/main.js:1624:15)
    at /Users/me/repo/triadica/ts-workflow/node_modules/esbuild/lib/main.js:1266:28
    at runOnEndCallbacks (/Users/me/repo/triadica/ts-workflow/node_modules/esbuild/lib/main.js:1046:63)
    at buildResponseToResult (/Users/me/repo/triadica/ts-workflow/node_modules/esbuild/lib/main.js:1264:7)
    at /Users/me/repo/triadica/ts-workflow/node_modules/esbuild/lib/main.js:1377:14
    at /Users/me/repo/triadica/ts-workflow/node_modules/esbuild/lib/main.js:678:9
    at handleIncomingPacket (/Users/me/repo/triadica/ts-workflow/node_modules/esbuild/lib/main.js:775:9)
    at Socket.readFromStdout (/Users/me/repo/triadica/ts-workflow/node_modules/esbuild/lib/main.js:644:7)
    at Socket.emit (node:events:527:28)
    at addChunk (node:internal/streams/readable:324:12)
^C
=>>

Also tried to run vite build and it worked correctly with same configuration(default glsl()).


update: looks like first problem is I was using mts directly from my app. I should compile all to .mjs and try again.


update: I can get it work by specifying optimizeDeps.exclude to disable ops.

Unable to import glsl file properly

Hi, I am working on a simple three.js project. I am trying to build and import a custom shader into my js code. However, after I installed the vite-plugin-vlsl following every step in the README.md file, I still could not get my js to read the glsl file properly and got the error as following:
Uncaught SyntaxError: Unexpected token '{' (at vertex.glsl?t=1679695882090&import:1:13)

I have restarted the server many times and also tried to tweak the code in the package.json file and vite.config.js file following the discussion in #1

Because the error I keep getting is the same error you would get when you don't have the plugin installed, I checked many times to make sure the setup is correct in every file, but I am still lost at what I am missing here. Thank you for your help in advance!

My package.json file:

{
  "name": "skin-earth",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview"
  },
  "devDependencies": {
    "vite": "^4.2.0",
    "vite-plugin-glsl": "^1.1.2",
    "vite-plugin-string": "^1.2.1"
  },
  "dependencies": {
    "three": "^0.150.1"
  }
}

vite.config.js file

import glsl from 'vite-plugin-glsl';
import { defineConfig } from 'vite';


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

my vertex.glsl file

void main() {
    gl_Position = vec4([1, 0, 0, 1]);
}

my main.js file

import './style.css'
import * as THREE from 'three'
import vertexShader from './shader/vertex.glsl'

console.log(vertexShader)

Migration to v0.3.0

Starting from v3.0.0, Vite uses node: imports which are supported in v16.0.0+ and v14.18.0+ of Node.js.

This is a intended breaking change because Node v15 is already EOL.

In v0.3.0 this plugin was updated to be a pure ESM, this means it cannot be require()'d from CommonJS anymore.

The goal of this issue is to demonstrate how vite-plugin-glsl should be used in case you're experiencing some problems after installation and what are some possible workarounds.

1. Recommended Usage:

  • Update your project to an ESM module by adding "type": "module" in your package.json. When using <npm|yarn|pnpm> create vite this comes by default with Vite v3.0.0+.

  • In your vite.config.js (or vite.config.ts) use this plugin as usual:

import { defineConfig } from 'vite';
import glsl from 'vite-plugin-glsl';

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

2. CommonJS Project With Config Module:

  • If for any reason you cannot add "type": "module" to you package.json, be sure to rename your vite.config file to vite.config.mjs (or vite.config.mts).

  • This will allow you to import this package by using top-level-await:

import { defineConfig } from 'vite';
const glsl = (await import('vite-plugin-glsl')).default;

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

3. CommonJS Project Without Config Module:

  • If you're stuck with a CommonJS project and for some reason you don't want to (or cannot) rename your vite.config file, you can use an async function to define a config object in your vite.config.js (or vite.config.ts):
import { defineConfig } from 'vite';

export default defineConfig(async () => {
  const glsl = (await import('vite-plugin-glsl')).default;

  return {
    plugins: [glsl()]
  }
});

As a last resort, if anything above don't work in you case, you can still use v0.2.2 of this plugin by running:

npm i [email protected] --save-dev
# or
yarn add [email protected] --dev

Here you can find more info about Vite v3.0.0 and this is a great Gist about ESM packages.

Typscript Support for Importing Shaders

Missing module declarations for the shader file extensions.

Easy solution and its the only thing missing for complete typscript support.

Add:

glsl.d.ts
vert.d.ts
frag.d.ts

ex.

declare module '*.glsl' { const content: string; export default content; }

Absolute path support

Hi !

In my projects, I organise my glsl code by components like so:

root
├── src/
│   ├── utils/
│   │   └── glsl/
│   │       ├── chunk1.glsl
│   │       └── chunk2.frag
│   ├── components/
│   │   └── Cube/
│   │       ├── index.js
│   │       └── index.frag
│   │       └── index.vert
│   └── main.js
├── vite.config.js
└── package.json

It seems that the loader doesn't support absolute import paths, which makes it really tedious for me to use. I don't really want to change my way of coding because of a tool that should help me. Do you plan to add this feature?

// index.frag
precision highp float;

#include /utils/glsl/chunk1.glsl;

out highp vec4 fragColor;

void main (void) {
  fragColor = chunkFn();
}

As far as I know, there is no such feature in any glsl loader.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.