Missing "Shaders/pass.fragment.fx" when using PassPostProcess

I just tried to update BabylonsJS from version 7.32.0 to the latest version. It seems that 7.32.0 is the last version that is working for me. If i use 7.32.1 or newer i get an “Shaders/pass.fragment.fx - 404” Error (ESM build) when i want to use a PassPostProcess. I checked the source a bit. It seems that _gatherImports is called to late.
This line triggers the error: Babylon.js/packages/dev/core/src/PostProcesses/postProcess.ts at master · BabylonJS/Babylon.js · GitHub

_gatherImports is called afterwards here: Babylon.js/packages/dev/core/src/PostProcesses/postProcess.ts at master · BabylonJS/Babylon.js · GitHub

The issue seems to be this line in the ‎EffectWrapper constructor: Babylon.js/packages/dev/core/src/Materials/effectRenderer.ts at master · BabylonJS/Babylon.js · GitHub

Before I jump into fixing this (and thank you so much for reporting), @sebavan / @Evgeni_Popov are you aware of changes made recently to the effect renderer/postprocess architecture?

Ideally we need a page or a code example to understand your code path and see why you are not going through the gather

1 Like

Here is a very basic example: BabylonJs - Error
You can see in the network tab that there is a 404 error for pass.fragment.fx.

This is all the code:

import { Scene } from "@babylonjs/core/scene.js";
import { Engine } from "@babylonjs/core/Engines/engine.js";
import { FreeCamera } from "@babylonjs/core/Cameras/freeCamera";
import { Vector3 } from "@babylonjs/core/Maths/math.vector.js";
import { PassPostProcess } from "@babylonjs/core/PostProcesses/passPostProcess.js";

const canvas = document.getElementById("bjs-canvas") as HTMLCanvasElement;
const engine = new Engine(canvas);
const scene = new Scene(engine);

const camera = new FreeCamera("camera1", new Vector3(0, 5, -10), scene);
camera.setTarget(Vector3.Zero());
camera.attachControl(canvas, true);

new PassPostProcess("pass1", 1.0, camera); //<-- the error is here 

engine.runRenderLoop(() => scene.render());

In your example, pass.fragment is searched in src/Shaders/ instead of dev/core/src/Shaders/.

We do import("../Shaders/pass.fragment") in the code, so it seems it is a problem of what is the current working directory.

cc @RaananW in case it could be a project configuration problem.

Yes you are importing the shader and the import works but i think you are using the shader/effect before the shader is loaded.
In my example i just added this line new FxaaPostProcess("fxaa1", 1.0, camera);.
Fxaa works without issues. Whats the difference between FxaaPostProcess and PassPostProcess?
In the network tab you can see that all shaders are loaded corractly but it still tries to load the pass.fragment.fx directly. I really think its a timing issue on your side.

That’s a race condition issue for sure. pass fragment is actually being loaded, you can see it in the network tab, but it is loaded at the same tick as the effect creation.
Now, I don’t know if it is something in your code or something in babylon, but looking at the simple code it does feel like something we should solve on our side.

You can solve it on yours as well, if you want, but actually importing the shader as a static import in your code. This is a temporary solution, but will let you continue your work on the scene while we try to understand what happens here

Following up on this, I have a better solution that will make it all work.

You need to pass blockCompilation: true in the constructor. it is the 8th variable, so the call will be a little tricky:

new PassPostProcess("pass1", 1.0, camera, undefined, undefined, undefined, undefined, true);

Not pretty, but solves it instantly. we internally will probably change that to true per default, but we need to discuss that first.

2 Likes

I just updated to version 7.35.0. Everything is working now without a change on my side.
Thank you everyone, good job :slight_smile:

2 Likes