Node based material

Hello,

We have been thinking for 4.1 (yes, early thinking indeed) to add a Node Material in the framework. What I mean by that is a fully customizable material system relying on blocks that you could from outside the babylon code mix and match as you please.

This would allow customization like Shader Builder but also simplify the creation of materials for artists used to deal with this kind of tools.

We would try to base our default materials (standard, pbr) on this system to ensure you do not need any hacks to customize them and that back compat would naturally flow through the system.

I have created the following github issue to track it: Create a node based system for material · Issue #6012 · BabylonJS/Babylon.js · GitHub

As it is a big addition I am polling the community to see who would be interested:

  • I am in
  • I do not know why I would use it but it sounds cool
  • This is useless

0 voters

Also do not hesitate to comment if you have any thoughts, requirements to be taken in consediration during the Dev. I am still far from it as I first need to finish SSS :slight_smile: but this time I ll take a head start.

6 Likes

This will be really cool!

2 Likes

Nice idea. I suppose this will be a webapp, and will output material code automatically?

[edit] In case you’re heading to a standalone app, this project may take your interest: GitHub - CedricGuillemet/Imogen: GPU Texture Generator

1 Like

dear @sebavan let me know if any help can i do

1 Like

Actually @Deltakosh implemented the foundation of it (code based generation) and @trevordev is creating a UI that will be embedded Like the Inspector to ease the creation.

A json like format is also in creation to bridge the gap between the UI and the code API :slight_smile:

@PatrickRyan is helping on the design with its long standing tech art Background :slight_smile:

Goal is to be released early in 4.1 to better test and refine before the end of the release.

@nasimiasl, for sure your creativity as a user will be a tremendous help to improve it a lot as soon as we will land early builds of it. @TheEntireCommunity, you ll be encouraged to go nuts to better address the limitation we might have.

4 Likes

@nasimiasl You can find a first version here: GitHub - BabylonJS/Babylon.js at node-material

And here is an example of code that works for now:

var createNodeMaterial = function(scene) {
    var nodeMaterial = new BABYLON.NodeMaterial("node", scene, { emitComments: true });
    var diffuseTexture = new BABYLON.Texture("/playground/textures/bloc.jpg");
    var ambiantTexture = new BABYLON.Texture("/playground/textures/crate.png");

    // Blocks

    // Vertex
    var morphTargets = new BABYLON.MorphTargetsBlock("morphTargets");

    var worldPos = new BABYLON.Vector4TransformBlock("worldPos");
    morphTargets.connectTo(worldPos);
    worldPos.transform.setAsWellKnownValue(BABYLON.NodeMaterialWellKnownValues.World);

    var worldPosdMultipliedByViewProjection = new BABYLON.Vector4TransformBlock("worldPos * viewProjectionTransform");
    worldPos.connectTo(worldPosdMultipliedByViewProjection);
    worldPosdMultipliedByViewProjection.transform.setAsWellKnownValue(BABYLON.NodeMaterialWellKnownValues.ViewProjection);

    var vertexOutput = new BABYLON.VertexOutputBlock("vertexOutput");
    worldPosdMultipliedByViewProjection.connectTo(vertexOutput);

    // Pixel
    var diffuseTextureBlock = new BABYLON.TextureBlock("diffuseTexture");
    diffuseTextureBlock.texture.value = diffuseTexture;

    var ambiantTextureBlock = new BABYLON.TextureBlock("ambiantTexture");
    ambiantTextureBlock.texture.value = ambiantTexture;

    var multiplyBlock = new BABYLON.MultiplyBlock("multiply");
    diffuseTextureBlock.connectTo(multiplyBlock);
    ambiantTextureBlock.connectTo(multiplyBlock);

    var fog = new BABYLON.FogBlock("fog");
    worldPos.connectTo(fog);
    multiplyBlock.connectTo(fog);

    var imageProcessing = new BABYLON.ImageProcessingBlock("imageProcessing");
    fog.connectTo(imageProcessing);

    var pixelOutput = new BABYLON.FragmentOutputBlock("pixelOutput");
    imageProcessing.connectTo(pixelOutput);

    // Add to nodes
    nodeMaterial.addOutputNode(vertexOutput);
    nodeMaterial.addOutputNode(pixelOutput);

    // Build
    nodeMaterial.build(true);

    // Fog
    scene.fogMode = BABYLON.Scene.FOGMODE_EXP;
    scene.fogDensity = 0.1;
    scene.fogColor = new BABYLON.Color3(0.9, 0.1, 0.85);

    return nodeMaterial;
}

2 Likes

i can help on UI Editor too

but for Nodes i have a idea

we can Make Node Template base and Node Templates Operators
let i explain by Code

// some default Templates

var nT1 = new NodeBlock.nodeTextures({  texture:{ path: 'teture path'  , ... }   });
var nT2 = new NodeBlock.nodeTextures({  texture:{ path: 'teture path'  , ... }   });
var nT3 = new NodeBlock.nodeTextures({  texture:{ path: 'teture path'  , ... }   });

var nO1 = new NodeOperators.nodeMix({  formule :' $T1 * $T2  - $T3  ' ,  
                                {T1: nT1 , T2:nT2 , T3:nT3  }  } );

i know it is so different but that is flexible

1 Like

Not that different just another type of node. And this is the beauty of it:)

2 Likes

maybe that is rude i write (wish @sebavan don’t angry about that ) it now ( i miss this project when that start )
i can sort all shader part we have and all helper method we can attach and then we make

node template base

then we talk about all prototype that template input and have output
i can make Node UI too (in javascript )

something like that

LiveNodesLiveUpdate

then member can make a namespace and under that name space they can make custom template (UI can be autogenerated)

and we can export them by Json and endpoint shaderMaterial

2 Likes

No worries @nasimiasl, it is not rude at all :slight_smile:

The idea is indeed pretty similar but more hooked directly in the core of Babylon. It should ease actually ease a lot what you are doing in the shader material.

I can totally see them as complementary thingy.

1 Like