BSL: write node materials like its glsl!

Hello everyone!

I have been looking to write some custom materials recently and I felt we were missing something like ThreeJS TSL. So I am very excited to bring you today this new tool, I hope you will like it :eyes:

Context

I first tried ShaderMaterial: very flexible, but don’t integrate well with existing BabylonJS features such as shadows and lighting models. Then I went for MaterialPlugin but it was very hacky and finding the right places to inject the code didn’t feel right.

Thankfully we have NodeMaterial, which solves all the issues mentionned above! But the visual editor does not scale well for complex shaders in term of readability and refactorings (spaghettis are inevitable)

I then decided to use the code API that solves these issues. Here is for example how we can sample a texture:

const uv = new InputBlock("uv");
uv.setAsAttribute("uv");

const albedoTexture = new TextureBlock("albedoTexture");
albedoTexture.target = NodeMaterialBlockTargets.Fragment;
albedoTexture.convertToLinearSpace = true;
albedoTexture.texture = Textures.CRATE_ALBEDO;

uv.output.connectTo(albedoTexture.uv);

Okay that works, but if you know your way around glsl/wgsl, you know that’s a lot of lines for something that used to be quite simple.

Babylon Shading Language

Enter the new Babylon Shading Language (BSL): a thin wrapper around node material blocks to allow you to write this instead:

const uv = BSL.vertexAttribute("uv");
const albedoTexture = BSL.textureSample(Textures.CRATE_ALBEDO, uv, { convertToLinearSpace: true });

As you can see, the syntax is much closer to glsl/wgsl and it’s much shorter without compromising on expressivity!

I find it much easier to read, write and reason about and you can adopt it incrementally in your projects as it is fully compatible with the native blocks ^^

Here is a Before and After comparison for one of my shaders ^^

Usage

I didn’t wrap all blocks yet, I am wrapping them as I need them but you can also contribute of course!

Let me know what you think!

10 Likes

Nice idea dude! really cool

1 Like

Thanks a lot :slight_smile: I may also do something similar for the new frame graph api when it releases haha

2 Likes

I’ve been reading a lot about TSL lately, and the more I learn, the more I realize how valuable it would be to have something similar in BabylonJS!
I’m going to dive into what you’ve built and see if I can integrate it into my projects. :slight_smile:

1 Like

Yes, TSL was a big inspiration while making BSL ^^ Let me know how it works out for your projects :wink:

I have a question for you @CrashMaster and maybe @Deltakosh can also give an opinion.

Why create a new Shading Langage? TSL will eventually create a shader from the javascript code. A shader which is then put into a Material.

So I wonder, couldn’t we simply extend what TSL does so that we could do something like this?

import { texture, uv } from 'three/tsl';

const detail = texture( detailMap, uv().mul( 10 ) );

const material = new BABYLON.MeshStandardNodeMaterial();
material._fragmentOutputNodes = texture( colorMap ).mul( detail );

I’m understand that ThreeJS and BabylonJS node materials don’t work the same way, but isn’t there a way to make TSL work with BJS at the shader level?
TSL already has a great community with a LOOOOT of features so it would be a shame to have to code it again for BJS. it sounds like reinventing the wheel.

What do you think?

1 Like

That’s a fair question, having TSL work for both BabylonJS and ThreeJS would be very nice.

The short answer is that it felt very easy to wrap the existing node material blocks in functions and I didn’t need more than that ^^

The longer answer is that BabylonJS shaders have many special imports for stuff like instances, lights and shadows that are resolved by the engine before compilation, and TSL cannot generate these imports or it generates ThreeJS specific syntax?

So while you could maybe make a ShaderMaterial out of TSL, you would not get the nice integration with Babylon’s features you get from NodeMaterial and BSL.

I don’t know much about TSL besides the issue it is trying to solve and how it works broadly, so I don’t know how much work would be needed to make it work with Babylon :thinking:

2 Likes