ShadowDepthWrapper - fails with fx files, works with equivalent shader strings

Note: A playground example is not possible, a minimal example is provided for download

First of all, this issue directly relates to using shader fx files, so the playground is not an option (please correct me if I’m wrong). I’ve done my best to produce a minimal example, and have uploaded it here. The example is an html page and requires loading from a webserver. Note: the page takes a minute to start up since it loads the max babylon core from the CDN. Using the max core is important for meaningful Babylon.js errors, as you will see.

 
Summary of the issue

Here’s the issue: I’ve got a custom shader who’s source I’m putting into .fx files. When creating a material from the shader and adding ShadowDepthWrapper, Babylon.js throws an error on initialization:

Uncaught (in promise) TypeError: shader.substring is not a function
effect.functions.ts:228

…and no shadow is shown.

if I don’t include a ShadowDepthWrapper, the material from the fx shader source works fine.

If I copy the .fx files into javascript strings and create a material from these strings, instead of from the fx files, adding a ShadowDepthWrapper works fine.

 
Overview of the downloadable sample

The minimal example, linked above, contains a minimal shader source both as .fx files, and as js strings in “index.js”. It creates one material from each of these sources and adds a ShadowDepthWrapper to each material. Finally, it adds an object to the scene and connects the material based the js string shader source. This material works fine, as one would expect.

If you open “index.html” and go to the second “COMMENT POINT” (do a search), you can swap out the material based on the js string shader source for the material based on the fx file shader source. Running the minimal example with this change produces the issue under discussion.

Subsequently, if you go to the first “COMMENT POINT”, you can comment out the creation of the ShadowDepthWrapper for the material based on the fx file shader source. Running the minimal example with this change produces no error, but (of course) the shadow is not in the proper shape. This shows that the issue is specific to ShadowDepthWrapper.

 
Preliminary Debug work

FYI, I did a bit of debugging, and it looks like IPipelineGenerationOptions._loadShader() is expecting it’s first parameter, shader, to be a string, but when ShadowDepthWrapper is used with fx files, it is called with shader being set to an object that looks like this:

Object { vertexSource: "", fragmentSource: "", vertexToken: "00b630db-4de1-4840-9dbd-62fbcf6d1dc4", fragmentToken: "00b630db-4de1-4840-9dbd-62fbcf6d1dc4" }

 
Environment used

I’m working with Babylon.js 8.4.0. I’m developing on FireFox. I’ve confirmed that the error shows in Chrome as well.

This PR should fix the problem:

Let me know if it works for you once it is merged, as I could not really test it properly.

1 Like