Vite shadowOnly shaders

Hi, I’m in the process of upgrading from babylonjs 4 to 7 in a vite/vue codebase.

So far there doesn’t seem to be a lot of actual changes for my limited setup, but what did change is the loading of shaders seemingly.

The following short section:

const ground = MeshBuilder.CreateGround("ground", { width: 2000, height: 2000, subdivisions: 2 }, scene);
    const material = new ShadowOnlyMaterial("shadowOnly", scene);
    ground.material = material;
    ground.receiveShadows = true;

Now suddenly tries to download a couple files :

  • shadowOnly.vertex.fx
  • shadowOnly.fragment.fx

In version 4 this did not happen, so any idea if there are some new imports I need to ensure to be loaded or did shader handling change somewhat and do I need to actually have those files somewhere downloadable?

I’ve tried importing

import "@babylonjs/materials/shadowOnly/shadowOnly.fragment";

directly, but that did not have any effect.

cc @RaananW

I’ve just tried to create a new vite/vue/babylonjs project and I have no issues:

app.ts

import { ArcRotateCamera } from "@babylonjs/core/Cameras/arcRotateCamera";
import { Engine } from "@babylonjs/core/Engines/engine";
import { Vector3 } from "@babylonjs/core/Maths/math.vector";
import { Scene } from "@babylonjs/core/scene";
import { ShadowOnlyMaterial } from "@babylonjs/materials/shadowOnly/shadowOnlyMaterial";
import { Color3 } from "@babylonjs/core/Maths/math.color";

class App {
  constructor() {
    // create the canvas html element and attach it to the webpage
    var canvas = document.createElement("canvas");
    canvas.style.width = "98vw";
    canvas.style.height = "98vh";
    canvas.id = "gameCanvas";
    document.body.appendChild(canvas);

    // initialize babylon scene and engine
    var engine = new Engine(canvas, true);
    var scene = new Scene(engine);
    scene.ambientColor = new Color3(0.4, 0.4, 0.4)

    var camera = new ArcRotateCamera("Camera", -0.5, 0.8, 200, Vector3.Zero(), scene);
    camera.attachControl(canvas, true)

    const material = new ShadowOnlyMaterial("shadowOnly", scene);

    // run the main render loop
    engine.runRenderLoop(() => {
      scene.render();
    });
  }
}
new App();
{
  "name": "vite-project",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "scripts": {
    "dev": "vite",
    "build": "vue-tsc -b && vite build",
    "preview": "vite preview"
  },
  "dependencies": {
    "@babylonjs/materials": "^7.19.1",
    "vue": "^3.4.35"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^5.1.2",
    "typescript": "^5.5.3",
    "vite": "^5.4.0",
    "vue-tsc": "^2.0.29"
  }
}

Can you share your project?

3 Likes

I can confirm that it also works on my end with your code.

What’s even better/worse is that in a new project with just the main babylon code copied over from my main project, it also does not exhibit the extra shader download behaviour.

I don’t really understand what’s causing the divergent behaviour as nothing else in my project interacts with babylon.

My project is opensource, so sharing it is not a problem, it will require a bit of setup though as it also requires a python server to run and currently requires an npm link to get another of my libraries related to babylon code that is also in an upgrade process.

I’ve written instructions below on getting that setup, but I totally understand if it’s not something you’re interested in figuring out. I can see in the network tab that the following backtrace is the initiator of the shadowOnly.[vertex|fragment].fx files. I’m not sure if that helps in any way

main project: GitHub - Kruptein/PlanarAlly: A companion tool for when you travel into the planes. branch feature/dice-ui-rework
dice library: GitHub - Kruptein/planarally-dice branch feature/rework

in the dice lib:

npm i
npm run build
npm link

in the main project:

# server: (requires a recent python 3 install)
cd server
pip install -r requirements.txt
python planarally.py dev

#client
cd client
npm i
npm link @planarally/dice
npm run dev

Reproducing:

  1. Open a browser to localhost:8000,
  2. register an account, can be anything (e.g. test with pw test, this is purely local)
  3. create a new game
  4. in the bottom right of the screen there is a dice icon, pressing that should asynchronously load the 3D related code, which in my case logs a bunch of errors to the console about the shader

edit: The core babylonjs code is found under client/src/game/dice/environment

This is the file that I copied over to a clean project, using the same @planarally/dice linked lib, without issues.

1 Like

All setup & running. Generates an error:

Any ideas?

You’re probably using the wrong port, try with 8000 instead of 8080

I didn’t change anything however if I have to, please navigate me where should I change it.

As you can on the screenshot ports used are 8000 and 8080.

Why can’t I find the @babylonjs/core dependency in your client/package.json file?

8000 and 8080 are correct ports, you indeed don’t have to change anything.

The output you showed, is the result of browsing to http://localhost:8080, can you try http://localhost:8000 instead.

I originally had the core dependency in my package.json, but I saw that in your example project you gave earlier, you only specified the material so I tried that as well. Feel free to re-add it in your local version. As far as I can tell it had no effect.

1 Like

This is something for @RaananW to look at. Could you please?

it doesn’t read the shader code from the bundle.

Similar to this one:

Probably a side-effect issue. Cloning the repo right now

Wait, sorry - is there a simple reproduction here? Or is it really needed to clone two and install pip?

Sadly as I’m in the middle of doing the upgrades to babylon I can’t offer something better right now.

I tried doing a smaller reproduction in a standalone project, but haven’t been able to reproduce it there.

Is there a way for me to forcefully load all side-effects in the meantime to just verify if that’s the issue?

The thing is this - the shaders are already loaded/imported if you are importing from shadowOnlyMaterial. I assume you are not just trying to use the shaders.

Anyhow, try loading these in one of your main entry points:

import "@babylonjs/materials/shadowOnly/shadowOnly.fragment.js";
import "@babylonjs/materials/shadowOnly/shadowOnly.vertex.js";

This should populate them in the shader lib and should prevent babylon from trying to load them from the network.

I already tried those sadly.

I’ll dive deeper again myself later, thanks for trying to help

If you can somehow reproduce this in a simpler way I will be very happy to debug this. check also if side effects are not turned off for some reason and tree-shaking on rollup is not set to the maximum because it will remove these lines.

Isn’t it the case that the babylon build ignored these side effects?

Yes, this is already there. I also said that in my first sentence :slight_smile:

But for some reason, in this setup, these lines are being removed. Either side effects configuration of the bundler or global side-effects reduction. Or something else, but I will need a reproduction.

A different solution would be to actually serve these files, but I would rather not go down this path, it should work out of the box.

1 Like

Whatever I do it’s trying to get those chunks from

This is because they were not loaded to the shader store. Which usually means the side effects didn’t run.

1 Like

I am checking if some other changes might have caused that. will get back to you on this one

1 Like