Support custom attributes in NME (Custom blocks)

Hello,
My need was to use a custom attribute in node material editor, and this was painful, so I thought I’d post some feedback here.

More specifically, my need was to merge multiple meshes with their own texture. I added an attribute to identify which texture needs to be selected in the fragment shader.

I’ve seen this github issue and I disagree with the conclusion: the objective of NME is to AVOID writing code so if you need to write code then NME loses a lot of interest.

So far the identified solutions were:

  1. use a normal input block and add code to force a specific attribute
  2. create a new class inheriting NodeMaterialBlock
  3. use a custom block from a json file

I did eliminate the 1st solution because all switch selection code would need to be done with Lerp or GreaterThan blocks which would cause a texel fetch on ALL textures (way heavier on the GPU), unlike GLSL code with if/else statements.
The 2nd solution looked more complex than the 3rd and would not allow easy reuse/sharing of blocks, like json custom blocks allows.

So the caveats for the 3rd solution were:

  1. The custom block format and ‘code’ field does not make any distinction between vertex and fragment shader. I had to create 2 blocks:
    a. one for the vertex shader, declaring the attribute and copying to a varying. But the code is not added if no output is used, so I had to add a useless input that is copied to an output, and insert anywhere in the chain.
    b. one for the fragment shader, using the varying to select one of the texture inputs
  2. This was not enough as it looks attributes needs to be explicitly listed along the way while compiling the shader. So I has to overload the _buildBlock() function of my custom block and add my attribute name to ‘state.attributes’

I’m unsure what’s the right way to move forward, but I feel that custom json blocks should offer a way to support custom attributes, for instance with an additional “attributes” array property that is copied into state.attributes. I saw code for InputBlock that handles declaration of the attribute and varying automatically and that would have saved a lot of time and solved my use case.
On a lower priority, I feel that we should be able to write distinct vertex and fragment code (e.g. with preprocessor directive) but I don’t have any real use case if support for custom attributes is already there.

2 Likes

So basically we want to allow users to have a text field in a inputblock to set a custom attribute right?

1 Like

That would be really helpful, yes.
In my use case, I would still have to use a custom block for optimization reasons, but it would be simpler (only one block and no trick to force it into vertex shader)

1 Like