Material plugin, just to make sure

Hi,

I was playing with:
https://playground.babylonjs.com/#P8B91Z#35

Then, I wrote part of my material plugin so far, but I would like to confirm the big picture.
The following is an excerpt of the shader I am writing, and trying to inject into the plugin system.

I put my understanding of where the plugin hooks occur.


// ----- We are in the Vertex shader
// Section 1 : CUSTOM_VERTEX_DEFINITIONS

precision highp float;
attribute vec2 position;
uniform float u_Float;
varying vec2 v_position;
float u_Constant = 1.0;


void main ( void ){
        // Section 2: CUSTOM_VERTEX_MAIN_BEGIN

        vec4 xyzw = vec4( position, 0.0, u_Constant ).xyzw;

        //Section 3 : CUSTOM_VERTEX_UPDATE_POSITION
        gl_Position = xyzw;
        v_position = position;

}

// ----- We are in the Fragment shader now
//Section 4 : CUSTOM_FRAGMENT_BEGIN
precision highp float;
uniform float u_Float;
uniform vec2 screenSize;
varying vec2 v_position;

/*
Here are my math functions, skip
*/

// FragmentOutput

// !!! I am not sure that the section below still belongs to CUSTOM_FRAGMENT_BEGIN
#include <helperFunctions>
float u_Constant = 1.0;

void main ( void ){
// Section 5:  CUSTOM_FRAGMENT_MAIN_BEGIN

        float x = screenSize.x;
        float y = screenSize.y;
        float output1 = y * u_Float;
        vec2 st = v_position; // declared in the vertex 

        /* blabla, plenty of maths */

        float output0 = my_function(...);

        // this line below is never used directly. Instead, we apply a function to ${this._varColorName}, which is the pixel color we modified. Inpired by the PG of the beginning of this post.
        // I would use CUSTOM_FRAGMENT_BEFORE_FRAGCOLOR and set  ${this._varColorName} accordingly
        gl_FragColor = vec4( /*blabla*/, 1.0 ); <- don't use that directly, I guess. Too many things to take care of.

}
getCustomCode(shaderType) {
      return shaderType === "vertex" ? null : {
      
                  "CUSTOM_VERTEX_DEFINITIONS": `
                      -> content of section 1 
                  `,
                  "CUSTOM_VERTEX_MAIN_BEGIN": `
                      -> content of section 2
                      `,
      
                  //and so on
      };
}

Ok.
Is my overall understanding of the system correct?
Concerning the include in the fragment, is it in the right section?
Are there parts that should not be (re)written? (Especially in the vertex section)

Thanks,

This seems correct to me, I usually look through the shader code in the repo to find back the entry points :slight_smile:

Thanks :slight_smile:
Now I am still struggling: I recreated a PG and a NME to show the issue.

The goal is to apply the material to my shapes. They should appear cloudy, they just appear clean.

NME
PG

I tried my shader in the CYOS and it worked.

Now, to create the above simplistic example, I took a shader that was referenced on a thread of this forum. I guess it should be guaranteed to work.
What I did:

  • Pick an example in the forum, the easiest I could find.
  • Simplify it further
  • Export shader (you will get it following the NME link)
  • Adapt the exported shader to the plugin system

But nothing expected happens in the PG.
It is important to me to confirm that it is not only with my shader but with another one as well, that I have a similar issue.

Everything converges toward my misunderstanding of the plugin system.

May you please enlighten me? What am I doing wrong?
Thanks

You are almost there but you need to define the uniforms in use in your plugin with their associated values.

Also you should probably reuse as you can from the one defined in the material already like world and viewProjection :slight_smile:

you can learn how to define your uniforms here: Customizing Materials: The Community Ninja Tale | by Babylon.js | Medium in the latest example.

AAAAAannnnnnd, it works now :slight_smile:

Thanks a lot!

BTW, in that section

  getUniforms() {
    return {
      ubo: [{ name: "myColor", size: 3, type: "vec3" }],
      fragment: `#ifdef COLORIFY
                    uniform vec3 myColor;
                #endif`,
    };
  }

the ubo key is essential, but isn’t the fragment element redundant with the fact that we can already have it written in the fragment definition? either here: CUSTOM_FRAGMENT_BEGIN or here CUSTOM_FRAGMENT_DEFINITIONS?

it seems that you need to setup things in different places when they could all be packed in the same place, specifically in getCustomCode(shaderType)?

There may be a strategy behind it that I miss, but it would help with simplicity to have everything in the same place I guess :slight_smile:

thanks :+1:

You actually do not need it in the fragment itself, only in the getUniform definition and it will be injected in the right place:

Yes, I get this, but wouldn’t it have been easier not to need it in that method, but instead directly in the getCustomCode, with the rest of the shader definition?

It would avoid a “logic trip” to remove the uniforms in the shader to put them elsewhere and let them live in the code they belong to.

This is just an opinion, because I guess it would make life -much- easier for shader writers.

But don’t get me wrong, the opinion I am expressing is not an offense of any kind :slight_smile:

nope, as it will be redundant in webgl2 or webgpu when relying on ubos :slight_smile: it would be defined twice, once in the ubo and once in the shader. The goal to have it in the definition is to ever only use one of the definition depending on the hardware support. If we let it in the code, we won t be able to remove it.

Nice, understood ! Thanks a LOT sebavan :+1: :+1:

1 Like