How to properly set up a Vite project when using custom shaders and ShaderMaterial

Disclaimer: First of all, my whole JavaScript framework/setup/build system/etc. knowledge is very limited, so it can be very likely that I am missing something fundamental or basic.


I have set up a Vite-based project, where I am using Babylon.js through modules that were installed through NPM. I’m also using BABYLON.ShaderMaterial and custom vertex and fragment shaders. Now, ShaderMaterial loads custom shader files by default from ./src/Shaders, which is not good, because Vite does not deploy them when publishing (through vite build).

I can put the shaders into the /public directory and configure ShaderMaterial to load them from there through:

BABYLON.Engine.ShadersRepository = "/public/src/Shaders/"

Then the shader files get deployed… but into /src/Shaders/ (i.e., not /public/src/Shaders/) because that’s Vite’s convention.

So, now I’m stuck. Can I use different paths during development and after build? Can I deploy the shaders in a different way? How is this meant to be done?

I’m grateful for any advice—even if the advice says to stop using Vite use something else istead.

just import the things you need from the installed npm folders into the scripts that use them , eg :

import { NodeMaterial } from "@babylonjs/core/Materials/Node/nodeMaterial";

There is no need to configure BABYLON.Engine.ShadersRepository, just use relative paths when creating shaderMaterial.

For example.

new ShaderMaterial("", scene, "./shader/simple")

He will request /shader/, which actually means he will fetch the file /public/shader/

  1. First, your public directory should be in the root directory
    | – public
    | – public/Shaders
    | – src
    | – vite.config.ts
  2. Then re-use the use
    BABYLON.Engine.ShadersRepository = “/Shaders/”

However, when static resources in public are updated, hot updates are not triggered. So you may need to use the configuration for rollup in vite.

This gives you the flexibility to configure shader file build paths and then use them.

Hope this helps you

I think that’s not related to my question?!

That’s great advice. Thank you!
However, I still have to problem when creating a distribution-build through vite build, because it doesn’t deploy the shaders under "./shader/simple" to the distribution directory… unless I put everything into /public/?

My directory structure is as follows:

├─ index.html
├─ babylonscene.js
├─ src/Shaders/
│  ├─ simple.vertex.fx
│  ├─ simple.fragment.fx

I don’t really understand, how that setup would work with subpage/src/Shaders/ vs public/.

vite does not package files under src, unless you import it.

import shader from "./shader/"

My suggestion is to put the shader folder in the public folder.

Thank you, your post helped.
I thought I had to refer to resources like /public/src/Shaders/ during development and then /src/Shaders/ for the distribution build, but /src/Shaders/ works just fine during development as well due to the Vite server handling public paths automagically under the hood.

I just don’t quite understand what

output: {
  sourcemap: false,
  entryFileNames: 'assets/js/[name].[hash].js',
  chunkFileNames: 'assets/js/[name].[hash].js',
  assetFileNames: 'assets/[ext]/[name].[hash].[ext]',

does in the vite.config.js. Would you mind explaining?

This configuration is resource file output configuration, vite due to the internal is rollup, so the details of the document here: Configuration Options | Rollup

Also, if you want to trigger the shader to compile in vite, you must reference it, just as you would with a static resource file. Otherwise, you are advised to put the shader file in the public directory.

Alternatively, you can place the shader folder correctly into the dist output directory after build (there are some vite plugins to do this for you).